前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript —— New

JavaScript —— New

作者头像
FinGet
发布2019-06-28 14:37:38
5020
发布2019-06-28 14:37:38
举报
文章被收录于专栏:FinGet前端之路

热身 New 这个关键字 是创建对象的? JS中万物皆是对象。 new 关键字是用来继承的。 => 面向对象的基础

new

代码语言:javascript
复制
function DN(name, age) {
  this.name = name;
  this.age = age;
  this.salary = '30k';
}
DN.prototype.ability = 100;
DN.prototype.sayYourName = function(){
  console.log('I am' + this.name);
}
var person = new DN('张三', '18');
console.log(person.name); // 张三
person.sayYourName(); // I am张三

可以得出使用过New关键字之后生成的person对象具有哪些特点。 1:可以访问DN构造函数里的属性 2:可以访问到DN.prototype中的属性

经典继承(构造继承)

代码语言:javascript
复制
function Parent() {
  this.names = ['Bios', 'FinGet'];
}
function Child() {
  Parent.call(this);
}
var child1 = new Child();
child1.names.push('zhangsan');
console.log(child1.names); // ["Bios", "FinGet", "zhangsan"]

var child2 = new Child();
console.log(child2.names); // ["Bios", "FinGet"]

DNew

代码语言:javascript
复制
function DNew() {
  var obj = {}; // 创建一个空对象
  Constructor = [].shift.call(arguments); // 获取第一个参数即构造函数
  obj.__proto__ = Constructor.prototype; // 隐式原型指向显式原型 将obj的原型链指向构造函数,这样onj就可以访问到构造函数原型链上的属性
  Constructor.apply(obj, arguments); // 使用apply(call)改变构造函数this的指向到新建的对象,这样obj可以访问构造函数的属性。这里的arguments是剔除了第一个参数的。
  return obj; // 返回对象
}
var person = DNew(DN,'张三', '18');
console.log(person.name); // 张三
person.sayYourName(); // I am张三

存在的问题

构造函数是可能有返回值的!

返回对象
代码语言:javascript
复制
function DN(name, age) {
  this.name = name;
  this.age = age;
  this.salary = '30k';
  return {
  	name: name,
	salary: "30k"
  }
}
DN.prototype.ability = 100;
DN.prototype.sayYourName = function(){
  console.log('I am' + this.name);
}
var person = new DN('张三', '18');
console.log(person.name); // undefined
console.log(person.age); // undefined
person.sayYourName(); // error
返回基本类型
代码语言:javascript
复制
function DN(name, age) {
  this.name = name;
  this.age = age;
  this.salary = '30k';
  return "finget"
}
DN.prototype.ability = 100;
DN.prototype.sayYourName = function(){
  console.log('I am' + this.name);
}
var person = new DN('张三', '18');
console.log(person.name); // 张三
console.log(person.name); // 18
person.sayYourName(); // I am张三
  • 当构造函数的返回值为对象时,返回的内容能取到,其他内部属性和原型上的方法都取不到。
  • 当构造函数的返回值为基本类型时, 跟没写return语句效果一样。

改进DNew

代码语言:javascript
复制
function DNew() {
  var obj = {}; // 创建一个空对象
  Constructor = [].shift.call(arguments); // 获取第一个参数即构造函数
  obj.__proto__ = Constructor.prototype; // 隐式原型指向显式原型 将obj的原型链指向构造函数,这样onj就可以访问到构造函数原型链上的属性
  var result = Constructor.apply(obj, arguments); // 使用apply(call)改变构造函数this的指向到新建的对象,这样obj可以访问构造函数的属性。这里的arguments是剔除了第一个参数的。
  return typeof result === 'object' ? result : obj; // 返回对象
}

当返回null的时候

当构造函数返回null的时候,我们应该返回obj而不是result

代码语言:javascript
复制
function DNew() {
  var obj = {}; // 创建一个空对象
  Constructor = [].shift.call(arguments); // 获取第一个参数即构造函数
  obj.__proto__ = Constructor.prototype; // 隐式原型指向显式原型 将obj的原型链指向构造函数,这样onj就可以访问到构造函数原型链上的属性
  var result = Constructor.apply(obj, arguments); // 使用apply(call)改变构造函数this的指向到新建的对象,这样obj可以访问构造函数的属性。这里的arguments是剔除了第一个参数的。
  return typeof result === 'object' ? result || obj : obj; // 返回对象
}

typeof null == Object;

优化

var obj = {}; => var obj = new Object();我们在封装new,却在内部使用了new,所有需要改变一下

代码语言:javascript
复制
function DNew() {
  // var obj = {}; // var obj = new Object() 创建一个空对象 
  // var obj = Object.create(null);
  Constructor = [].shift.call(arguments); // 获取第一个参数即构造函数
  // obj.__proto__ = Constructor.prototype; 
  var obj = Object.create(Constructor.prototype);
  var result = Constructor.apply(obj, arguments); 
  return typeof result === 'object' ? result || obj : obj; // 返回对象
}

代码过程(我自己看)

代码语言:javascript
复制
// 热身
// New 这个关键字 是创建对象的?
// JS中万物皆是对象。
// new 关键字是用来继承的。 => 面向对象的基础

function DN(name, age) {
  this.name = name;
  this.age = age;
  this.salary = '30k';
}
DN.prototype.ability = 100;
DN.prototype.sayYourName = function(){
  console.log('I am' + this.name);
}
var person = new DN('张三', '18');
console.log(person.name);
person.sayYourName();
// 可以得出使用过New关键字之后生成的person对象具有哪些特点。
// 1:可以访问DN构造函数里的属性
// 2:可以访问到DN.prototype中的属性

// 要如何去实现
// 经典继承(借用构造函数的方式)
function Parent() {
  this.names = ['Bios', 'FinGet'];
}
function Child() {
  Parent.call(this);
}
var child1 = new Child();
child1.names.push('zhangsan');
console.log(child1.names); // ["Bios", "FinGet", "zhangsan"]

var child2 = new Child();
console.log(child2.names); // ["Bios", "FinGet"]

// 避免引用类型的属性,被所有实例对象共享

// 2、怎么获取原型链上的属性
// __proto__

function DNew() {
  // var obj = {}; // var obj = new Object() 创建一个空对象 
  // var obj = Object.create(null);
  Constructor = [].shift.call(arguments); // 获取第一个参数即构造函数
  // obj.__proto__ = Constructor.prototype; 
  var obj = Object.create(Constructor.prototype);
  var result = Constructor.apply(obj, arguments); 
  return typeof result === 'object' ? result || obj : obj; // 返回对象
}


(function(root, factory){
  root.$ = root.DN = factory();
})(this, function(){
  var DN = {
	DNew: function() {
	  // var obj = {}; // var obj = new Object() 创建一个空对象 
	  // var obj = Object.create(null);
	  Constructor = [].shift.call(arguments); // 获取第一个参数即构造函数
	  // obj.__proto__ = Constructor.prototype; 
	  var obj = Object.create(Constructor.prototype);
	  var result = Constructor.apply(obj, arguments); 
	  return typeof result === 'object' ? result || obj : obj; // 返回对象
	}
  };
  return DN;
})
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-02-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • new
  • 经典继承(构造继承)
  • DNew
    • 存在的问题
      • 返回对象
      • 返回基本类型
    • 改进DNew
      • 当返回null的时候
      • 优化
      • 代码过程(我自己看)
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档