new关键字
new一个函数,都会发生什么?
关于new这个关键字,我们都会用,但是如果问你new一个函数时会发生什么?我想你就懵了
看过红宝书的,可以很清晰的说出new后发生的四件事:
1. 创建一个新对象;
2. 将构造函数的作用域赋给新对象(因此this就指向了这个新对象);
3. 执行构造函数中的代码(为这个新对象添加属性);
4. 返回新对象;
我在学习原型和原型链时看到new一个函数时,JS编译器会做四件事:
1、创建一个新的空的对象;
2、把这个对象链接到原型对象上;
3、这个对象被绑定为this;
4、如果这个函数不返回任何东西,那么就会默认return this;
可以看出做的事情都相同,只是说法不同
接下来我们通过代码一步一步的来分析这四步
第一步:
创建一个新的空的对象
function Person() { }
var p = new Person();
第二步:
所谓将构造函数的作用域赋给新对象,就是给这个新对象构造原型链,链接到构造函数的原型对象上,从而新对象就可以访问构造函数中的属性和方法。(原型和原型链详解)
p.__proto__ = Person.prototype
第三步:
改变this的指向,通过函数call()方法让this指向p(也就是说this就是p)
Person.call(p, 'Andy');
实参Andy传入构造函数Person中,这样this.name = 'Andy',那么p.name = 'Andy',也就是说name属性被挂载到p对象上。
执行构造函数的代码,继承属性
function Person(name) { this.name = name } var p = new Person(); p.name;
第四步:
如果构造函数有返回值,则返回;否则,就会默认返回新对象。
总结——手写一个new
function _new(fn,...args){ const obj = {}; obj.__proto__ = fn.prototype; const res = fn.call(obj,args); return res instanceof Object ? res:obj; }
其中 res 为构造函数的返回值。
另外 ES5 提供了 Object.create 方法,该方法可以创建一个对象,并让新对象的__proto__属性指向已经存在的对象。如下:
function _new(fn,...args){ const obj = Object.create(fn.prototype); const res = fn.call(obj,args); return res instanceof Object ? res:obj; }
大致过程就是这样了~