var F=function(){
//this指向谁,在定义时是不知道的
};
var p=new F;
用new调用一个函数发生了这些事:
(1)新建一个对象
instance=new Object();
(2)设置原型链
instance.__proto__=F.prototype;
(3)让F
中的this
指向instance
,执行F的函数体。
(4)判断F
的返回值类型:
如果是值类型,就丢弃它,还是返回instance
。
如果是引用类型,就返回这个引用类型的对象,替换掉instance
。
注:
(1)如果没有写return,相当于return undefined,JavaScript中的函数都是这样。undefined是值类型的,因此丢弃它,返回instance。
(2)如果return this相当于返回一个引用类型的对象,它自己就是instance,无所谓替换不替换了。
(3)对instance并不需要设置它的constructor属性,这个属性在instance的原型中。
console.assert(!p.hasOwnProperty('constructor'));
console.assert(F.prototype.hasOwnProperty('constructor'));
而且,任意一个新函数在创建时,原型的constructor就已经设置好了。
var G=function(){};
console.assert(G.prototype.hasOwnProperty('constructor'));
console.assert(G.prototype.constructor===G);
于是,这也要求我们在对prototype重新赋值的时候,重新指定constructor属性。
F.prototype={
constructor:F
};
证明:
/* about the constructor
// instance.constructor is exactly instance.__proto__.constructor
function F() { }
console.assert((new F).constructor === F);
console.assert((new F).hasOwnProperty('constructor') === false);
console.assert(F.prototype.hasOwnProperty('constructor') === true);
// so if we change the prototype, we should also change the prototype's constructor.
function F(){}
F.prototype=new G;
F.prototype.constructor=F;
// if not, (new F).constructor===F.prototype.constructor===(new G).constructor===G.prototype.constructor===G;
网友评论