var F=function(){
//this指向誰翘悉,在定義時(shí)是不知道的
};
var p=new F;
用new調(diào)用一個(gè)函數(shù)發(fā)生了這些事:
(1)新建一個(gè)對象
instance=new Object();
(2)設(shè)置原型鏈
instance.__proto__=F.prototype;
(3)讓F
中的this
指向instance
,執(zhí)行F的函數(shù)體居触。
(4)判斷F
的返回值類型:
如果是值類型妖混,就丟棄它,還是返回instance
饼煞。
如果是引用類型源葫,就返回這個(gè)引用類型的對象,替換掉instance
砖瞧。
注:
(1)如果沒有寫return息堂,相當(dāng)于return undefined,JavaScript中的函數(shù)都是這樣块促。undefined是值類型的荣堰,因此丟棄它,返回instance竭翠。
(2)如果return this相當(dāng)于返回一個(gè)引用類型的對象振坚,它自己就是instance,無所謂替換不替換了斋扰。
(3)對instance并不需要設(shè)置它的constructor屬性渡八,這個(gè)屬性在instance的原型中。
console.assert(!p.hasOwnProperty('constructor'));
console.assert(F.prototype.hasOwnProperty('constructor'));
而且传货,任意一個(gè)新函數(shù)在創(chuàng)建時(shí)屎鳍,原型的constructor就已經(jīng)設(shè)置好了。
var G=function(){};
console.assert(G.prototype.hasOwnProperty('constructor'));
console.assert(G.prototype.constructor===G);
于是问裕,這也要求我們在對prototype重新賦值的時(shí)候逮壁,重新指定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;