成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

一道平常的面試題被鄙視引起的較真o( ̄ヘ ̄o#)

MadPecker / 3401人閱讀

摘要:第七問,可以看做,同上面的結(jié)果一樣得到一個匿名函數(shù),這個匿名函數(shù)與前面的以及后面的組成一個新的對象創(chuàng)建表達(dá)式,這個表達(dá)式在執(zhí)行時,會調(diào)用其中的構(gòu)造函數(shù),因此會彈出。

緣由

開通文章是為了能夠有個地方長篇大論今天遇到的問題
由于提了一個問題(見 這里),被人嘲諷。但是這個嘲諷我的人(@xiaoboost )的答案并不對,他的答案只是根據(jù)結(jié)果解釋能夠得出這個結(jié)果的執(zhí)行。至于為什么以及JavaScript在執(zhí)行過程中進(jìn)行了哪些判斷并沒有進(jìn)行詳細(xì)的解釋或者說完整的解釋。其余的幾個朋友要么鄙視這道題、要么鄙視我把運(yùn)算符優(yōu)先級牽扯進(jìn)來。最讓我納悶的是大家都認(rèn)為這里面不牽扯到運(yùn)算符的優(yōu)先級判斷。
在此,我以自己的理解來解釋一下JavaScript在執(zhí)行過程中進(jìn)行了哪些判斷和操作。

原始問題:
function Foo() {
  getName = function () {
    alert(1);
  };
  return this;
}
Foo.getName = function () {
  alert(2);
};
Foo.prototype.getName = function () {
  alert(3);
};
var getName = function () {
  alert(4);
};
function getName() {
  alert(5);
}

Foo.getName();
getName()
Foo().getName()
getName()
new Foo.getName()
new Foo().getName()
new new Foo().getName()
我的答案:

首先,JS中會對變量聲明和函數(shù)聲明在編譯階段進(jìn)行提升,所以實際代碼會表現(xiàn)成這樣:

// 此處是變量提升的演示,是在編譯階段進(jìn)行的
var getName;
function Foo() {
  getName = function () {
    alert(1);
  };
  return this;
}
function getName() {
  alert(5);
}

// 此處則只有到了執(zhí)行階段才會執(zhí)行
Foo.getName = function () {
  alert(2);
};
Foo.prototype.getName = function () {
  alert(3);
};
getName = function () {
  alert(4);
};

其次,除了第六問和第七問,所有有成員訪問運(yùn)算符(也叫屬性訪問器).的表達(dá)式,.的優(yōu)先級都是最高,沒有一個表達(dá)式有圓括號,有圓括號的要么是函數(shù)調(diào)用,要么是new 運(yùn)算(對象創(chuàng)建表達(dá)式)的組成部分。

這里專門說明沒有圓括號是因為看到這個問題原作者自己的分析文章將new Foo().getName()中的new Foo()先執(zhí)行解釋為由于圓括號的優(yōu)先級高于.。附上問題原作者自己的分析文章:http://www.cnblogs.com/xxcang...

以下為各問題的數(shù)字輸出以及為什么:

第一問

2,直接調(diào)用Foo函數(shù)的getName方法。

第二問

4,變量聲明和函數(shù)聲明會在編譯階段被提升。此時,函數(shù)聲明會覆蓋變量聲明。但是到了執(zhí)行階段,如果變量有賦值操作,那么變量會因賦值而覆蓋之前的函數(shù)聲明。因此第二問的getName()實際執(zhí)行的是賦值了匿名函數(shù)function () {alert(4)}的函數(shù)表達(dá)式。

第三問

1,.運(yùn)算符優(yōu)先級最高,按照.運(yùn)算符的關(guān)聯(lián)性從左往右先計算左操作數(shù),Foo()是一個函數(shù)調(diào)用表達(dá)式,函數(shù)內(nèi)部在執(zhí)行時,由于函數(shù)內(nèi)部沒有查找到局部變量getName,因此引擎會沿著作用域鏈向上查找getName變量。在全局作用域中找到getName變量(同時也是window的屬性/方法),給它賦值一個新的匿名函數(shù)function(){alert(1)}returnthis此時指向當(dāng)前方法所屬的對象window,因此,計算右操作數(shù)時,就是調(diào)用了window對象上的getName方法。而前面左操作數(shù)Foo()中已經(jīng)給getName變量重新賦值了一個匿名函數(shù),因此會出現(xiàn)新賦值函數(shù)所彈出的數(shù)字1。

第四問

1,getName()已經(jīng)因為前面的Foo()的調(diào)用而賦值了新的匿名函數(shù),因此彈出數(shù)字1。

第五問

2,new可以與Foo結(jié)合組成一個沒有參數(shù)的對象創(chuàng)建表達(dá)式,但是這樣它的優(yōu)先級低于".",因此這里.運(yùn)算符優(yōu)先級高于new和函數(shù)調(diào)用(),整個表達(dá)式則可以理解為:new (Foo.getName)(),當(dāng)Foo.getName執(zhí)行完畢會返回一個匿名函數(shù)function(){alert(2)},此時會與new運(yùn)算符、()組成一個新的表達(dá)式:new function(){alert(2)}(),這是一個對象創(chuàng)建表達(dá)式,這個表達(dá)式在執(zhí)行執(zhí)行的時候,構(gòu)造函數(shù)部分function(){alert(2)}會被執(zhí)行,結(jié)果就是2。另外,對象創(chuàng)建表達(dá)式在沒有傳入?yún)?shù)的情況下可以省略括號,因此原題中的new Foo.getName();可以把后面的括號省略掉new Foo.getName,結(jié)果一樣。

第六問

3,帶有參數(shù)的對象創(chuàng)建表達(dá)式(new constructor())和成員訪問表達(dá)式的優(yōu)先級是一樣,這里就牽扯到應(yīng)該理解成
(new Foo()).getName()還是new (Foo().getName)()。如果是new (Foo().getName)(),那么在執(zhí)行Foo()時,它是一個函數(shù)調(diào)用,優(yōu)先級低于帶參數(shù)的new,因此這樣不行。那么只能是(new Foo()).getName()。new Foo()實例化一個對象,然后通過.訪問getName屬性,對象本身沒有這個屬性,順著原型鏈查找到Foo.prototype中有這個屬性,并且賦值了一個匿名函數(shù)。最后通過函數(shù)調(diào)用運(yùn)算符調(diào)用它,得到3。

第七問

3,可以看做 new((new Foo()).getName)(),(new Foo()).getName同上面的結(jié)果一樣得到Foo.prototype.getName一個匿名函數(shù):function () {alert(3)},這個匿名函數(shù)與前面的new以及后面的()組成一個新的對象創(chuàng)建表達(dá)式new function () {alert(3)} (),這個表達(dá)式在執(zhí)行時,會調(diào)用其中的構(gòu)造函數(shù)function (){alert(3)},因此會彈出3。

以上是我對這個問題的解釋,其中第六問得到@zonxin 的解答,再次感謝,附上地址:https://segmentfault.com/q/10...

最后,附上我被嘲諷并且被4個人"踩"的問題地址,如果覺得我的解答是正確的,麻煩幫我"平反"╥﹏╥...;如果有錯誤的地方,請留言指出,我會十分感謝。
我的原問題地址:https://segmentfault.com/q/10...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/81681.html

相關(guān)文章

  • 掌握面試——彈出框實現(xiàn)(一道題中包含布局/js設(shè)計模式)

    摘要:面試會進(jìn)入下一個環(huán)節(jié)。如果在頁面中有多個按鈕,那么這個彈出窗要如何實現(xiàn)同上,根據(jù)之前的建議在回答問題之前要問清楚問題中模棱兩可的地方。是否觸發(fā)不同按鈕彈出的窗口現(xiàn)實的內(nèi)容不同。 這道面試題,當(dāng)初我面試的時候被問過兩次,因此比較深,此外,我記得還有設(shè)計模式的考察,所以,有深刻的體會。 面試題主要考察什么 面試不是個輕松的活,不管是對面試官還是面試者都一樣。對于面試官來說,別的先不管,首先...

    defcon 評論0 收藏0
  • 一道js閉包面試學(xué)習(xí)

    摘要:然后最外層這個函數(shù)會返回一個新對象,對象里面有一個屬性,名為,而這個屬性的值是一個匿名函數(shù),它會返回。 最近看到一條有意思的閉包面試題,但是看到原文的解析,我自己覺得有點迷糊,所以自己重新做一下這條題目。 閉包面試題原題 function fun(n, o) { // ① console.log(o); return { // ② fun: function(m) ...

    plus2047 評論0 收藏0
  • 簡單說 一道JS閉包面試

    摘要:說明最近看到這樣一段代碼問三行的輸出分別是什么覺得有點意思,和大家一起來聊聊。說到這里,這道題基本上可以解決了,希望大家能聽明白我上面說的話,下面的就簡單了。 說明 最近看到這樣一段代碼 function fun(n,o){ console.log(o); return { fun:function(m){ return fun...

    mushang 評論0 收藏0
  • 簡單說 一道JS閉包面試

    摘要:說明最近看到這樣一段代碼問三行的輸出分別是什么覺得有點意思,和大家一起來聊聊。說到這里,這道題基本上可以解決了,希望大家能聽明白我上面說的話,下面的就簡單了。 說明 最近看到這樣一段代碼 function fun(n,o){ console.log(o); return { fun:function(m){ return fun...

    Lin_YT 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<