new
的本质
执行构造函数,返回实例对象
- 创建一个空对象,作为将要返回的对象实例
- 将这个空对象的原型,指向构造函数的prototype属性
- 将这个空对象赋值给函数内部的this关键字
- 开始执行构造函数内部的代码
根据这几步可以模拟写一个和new
命令一样功能的方法出来
1 2 3 4 5 6 7 8 9
| function _new(/* constructor, param, ... */) { var args = [].slice.call(arguments); // 类数组对象转化成数组 var constructor = args.shift(); // 获取数组第一个,并在原有数组中删除,构造方法与参数分离 var context = Object.create(constructor.prototype); // 通过构造函数的prototype属性指定原型 var result = constructor.apply(context, args);// 执行构造函数体把属性帮到this上,这里this就是context啦 return (typeof result === 'object' && result != null) ? result : context; // 看返回值是什么类型,是对象就直接返回,不是则返回context }
var actor = _new(Person, "caidewu", 24);
|
如果构造函数内部有return语句,而且return后面跟着一个对象,new命令会返回return语句指定的对象;否则,就会不管return语句,返回this对象。
所以当一个构造函数返回的是一个function对象,那么这个构造函数是没有意义的,本质上变成一个普通的函数,其实是个工厂函数
1 2 3 4 5 6 7 8 9 10
| function A() { this.a = 'aaa'; return function() {console.log('hhh')}; }
var o1 = new A(); var o2 = A();
o1(); // hhh o2(); // hhh
|