Open
Description
new 的过程
new
关键字会进行如下的操作:
- 创建一个空的简单JavaScript对象(即
{}
); - 为步骤1新创建的对象添加属性
__proto__
,将该属性链接至构造函数的原型对象prototype
; - 将
this
指向步骤1新创建的对象 ; - 如果该函数没有返回对象,则返回
this
。
示例讲解
以下面代码为例讲解
function Animal (name) {
this.name = name;
}
var cat = new Animal('dog');
var cat = new Animal('dog');
是关键代码,js引擎在执行这句代码的时候,内部做了很多工作,用伪代码模拟一下其内部流程如下:
new Animal('dog') 相当于 {
var obj = {};
obj.__proto__ = Animal.prototype;
var result = Animal.call(obj, 'dog');
return typeof result === 'object' ? result : obj;
}
解析上述步骤:
1、新生成一个对象:创建一个空对象obj
;
2、链接到原型:把obj
的__proto__
指向了构造函数的Animal
的原型对象prototype
。
3、绑定this.call
,apply
,bind
:在obj
对象的执行环境中调用Animal
函数并传递参数dog
,相当于var result = obj.Animal('dog')
,当执行完这句话后obj
就产生了属性name
并赋值“dog”
。
4、返回新对象(如果构造函数有自己的return
,则返回该值):观察第三步的返回值,如果无返回值或者返回一个非对象值,则将obj
作为新对象返回,否则会将result
作为新对象返回。
实现一个简单的new方法
function _new() {
let target = {}; //创建的新对象
//第一个参数是构造函数
let [constructor, ...args] = [...arguments];
//执行[[原型]]连接;target 是 constructor 的实例
target.__proto__ = constructor.prototype;
//执行构造函数,将属性或方法添加到创建的空对象上
let result = constructor.apply(target, args);
if (result && (typeof (result) == "object" || typeof (result) == "function")) {
//如果构造函数执行的结构返回的是一个对象,那么返回这个对象
return result;
}
//如果构造函数返回的不是一个对象,返回创建的新对象
return target;
}
测试写的_new
方法
function Person(name) {
this.name = name;
};
Person.prototype.sayName = function () {
console.log(this.name);
};
const p = _new(Person, 'Tom');
p.sayName(); // Tom
创建对象的方法和区别
创建对象的三种方法
- 字面量(
var obj = {}
) new
构造器Object.create()
三种方法的区别
new和Object.create()区别
new
出的实例继承构造函数的属性,Object.create()
出的实例不继承构造函数的属性,Object.create(arg, pro)
创建的对象的原型取决于arg
,arg
为null
,新对象是空对象,没有原型,不继承任何对象;arg
为指定对象,新对象的原型指向指定对象,继承指定对象
对象字面量和Object.create区别
- 对象字面量不会调用
Object
构造函数, 简洁且性能更好; - 对象字面量是纯对象,
Object.create
是实例对象 - 对象字面量原型指向
Object
,Object.create(arg, pro)
原型取决于arg
- 对象字面量属性是非继承属性,
Object.create()
出的实例不继承构造函数的属性