Javascript中的new关键字

2016-03-09

new的本质

执行构造函数,返回实例对象

  1. 创建一个空对象,作为将要返回的对象实例
  2. 将这个空对象的原型,指向构造函数的prototype属性
  3. 将这个空对象赋值给函数内部的this关键字
  4. 开始执行构造函数内部的代码

根据这几步可以模拟写一个和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