基于segmentfault上的一道題
題目
function foo() {
getName = function () { console.log (1); };
return this;
}
foo.getName = function () { console.log(2);};
foo.prototype.getName = function () { console.log(3);};
var getName = function () { console.log(4);};
function getName () { console.log(5);}
new foo.getName (); // 第一種
new foo().getName (); // 第二種
new new foo().getName (); // 第三種
-
首先先了解下優(yōu)先級(jí)(由高到低)
MDN
由此可以知道new 的優(yōu)先級(jí)帶參數(shù)的比不帶的高
解析
- 第一種
new foo.getName ();'.'的優(yōu)先級(jí)比new高
所以先執(zhí)行foo.getName,在來(lái)執(zhí)行new
也就是new (foo.getName) ()// 返回一個(gè)foo.getName的實(shí)力 獲得就是2 - 第二種
new foo().getName ();主要猶豫的地方是先f(wàn)oo()函數(shù)運(yùn)算還是先new
foo()先new (foo().getName)()
new 先(new foo()).getName()
如果new 不帶參數(shù)的優(yōu)先級(jí)確實(shí)比函數(shù)調(diào)用的優(yōu)先級(jí)低,但現(xiàn)在new是帶參數(shù)的所有優(yōu)先級(jí)
所以執(zhí)行的(new foo()).getName()// foo()上的getName方法,但是沒有這個(gè)方法所以去原型上找,結(jié)果為3 - 第三種
new new foo().getName ();從上面分析得,new帶參數(shù)會(huì)優(yōu)先執(zhí)行,這是在從左至右的運(yùn)算基礎(chǔ)下實(shí)現(xiàn)的
也就是第一步new (new foo().getName)()
第二步new ((new foo()).getName)()
最后進(jìn)行運(yùn)算 先計(jì)算new foo(), 在獲取getName,在對(duì)獲取內(nèi)容進(jìn)行new ()計(jì)算
new ((new foo()).getName)()也就是new (foo.prototype.getName)()
返回的就是3, 具體可以看下面new 原理解析
new原理
在第三種解析中我們要計(jì)算 new (foo.prototype.getName)()的值,首先要明白new到底做了什么,其實(shí)就做了3件事
var obj = {};
obj.__proto__ = Base.prototype;
Base.call(obj);
第一步:創(chuàng)建一個(gè)空對(duì)象
第二步:綁定該對(duì)象的原型
第三部:調(diào)用構(gòu)造函數(shù) // 執(zhí)行了構(gòu)造函數(shù)的內(nèi)容
所以在 new (foo.prototype.getName)()也就會(huì)返回foo.prototype.getName的一個(gè)實(shí)例,并且執(zhí)行一次構(gòu)造函數(shù),也就是執(zhí)行console.log(3),打印3這個(gè)結(jié)果
