摘要:關于該問題的討論今天看到的一道面試題,感覺對理解的以及原型鏈和閉包很有幫助。自己并試著講述一下自己的理解,歡迎拍磚。進入上下文時,會獲取,函數聲明,變量聲明。
2017.3.27更新
今天在刷題的時候,突然發現之前已經有人在討論這道題了,而且還涉及到了運算符優先級的問題,這是自己一開始沒有想到的。(其實有人也說:程序寫多了,自然記住了什么情況下會發生什么樣的事情,但是為什么會發生這樣的事情,可能問起來一時還真回答不了。我就屬于這種狀態,所以一開始并沒有考慮到運算符優先級的問題)。
關于該問題的討論:
https://segmentfault.com/q/10...
https://segmentfault.com/a/11...
https://segmentfault.com/a/11...
題目:今天看到的一道面試題,感覺對理解JavaScript的Function以及原型鏈和閉包很有幫助。自己并試著講述一下自己的理解,歡迎拍磚。
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();
請問上述代碼的輸出結果是什么?
分析2,4,1,1,2,3,3
Foo.getName():函數調用輸出2很好理解,直接調用的Foo.getName();
getName():函數調用輸出為4,這和變量提升有關系了,因為在函數調用分為兩個步驟,第一進入上下文階段,第二為執行階段。進入上下文時,會獲取arguments,函數聲明,變量聲明。只有在執行階段才會進行變量賦值,而第四個是函數表達式,第五個為函數聲明,所以他們等同于下面的形式:
進入上下文階段:function getName(){alert(5);}
執行階段(將之前的getName函數給覆蓋掉了):getName=function(){alert(4);}
所以不管怎么調用,答案中都應該不會出現5。
Foo().getName()與第二次getName():第三個函數調用開始有迷惑性了。最后調用的getName函數,其實是全局的getName。第二次調用就成了Foo()函數中的那個,因為其前面沒有var,也就是說這個getName并不是一個私有變量,而是全局變量,所以將之前的全局中的getName函數在執行Foo()時會被覆蓋掉了。因此下一次再執行getName方法的結果就變成了1,而不是之前的4了。
另外也跟new關鍵字有關,因為Foo()前沒有使用new,所以不會創建新的對象,而且 Foo的調用應該屬于函數調用,所以返回的this其實是window對象,而不是Foo實 例(并沒有創建)。
new Foo.getName():調用其實是創建了一個Foo.getName的新的實例(函數本身也是Object),在創建對象的過程中執行到了alert(2)語句,所以就輸出為2;
new Foo().getName():調用是先根據Foo.prototyoe創建一個Foo的實例,調用getName方法時,因為自身沒有getName方法,會去原型鏈上找,最后調用到Foo.prototype.getName,所以就是輸出為3;
new new Foo().getName():第七個就是第五和第六個的結合,先創建一個Foo實例,然后再創建Foo實例的getName函數(也就是Foo.prototype.getName)的實例。在創建的過程中,執行到alert(3)語句,所以輸出3。
變化通過修改Foo()函數體,可以呈現出不同的調用變化。
Foo函數體內的getName前加上var(getName變成了私有變量),答案會變成:2,4,4,4,2,3,3。
Foo函數體內的getName前加上this(getName變成了屬性),答案會變成:2,4,1,1,2,1,1。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82203.html
摘要:忍者秘籍一書中,對于柯里化的定義如下在一個函數中首先填充幾個參數然后再返回一個新函數的技術稱為柯里化?;氐轿覀兊念}目本身,其實根據測試用例我們可以發現,函數的要求就是接受單一函數,例如但是與柯里化不同之處在于,柯里化返回的一個新函數。 歡迎大家再一次來到我的文章專欄:從面試題中我們能學到什么,各位同行小伙伴是否已經開始了悠閑的春節假期呢?在這里提前祝大家雞年大吉吧~哈哈,之前有人說...
摘要:今天看見一道面試題答案是多少答案是對方法不太了解就去搜了一下,里面也包含了對這道面試題的詳解。方法返回一個由原數組中的每個元素調用一個指定方法后返回值組成的新數組。使用方法處理數組時,數組元素的范圍在方法第一次調用之前就已經確定了。 今天看見一道面試題:[1,2,3].map(parseInt)答案是多少?答案是[1,NaN,NaN] 對map()方法不太了解就去搜了一下:Array....
摘要:但是有一個總的原則那就是總會指向,調用函數的那個對象。作為對象方法的調用函數作為某個對象的方法調用,這時就指這個上級對象。 showImg(https://segmentfault.com/img/bVbnvF7?w=750&h=422); 這是前端面試題系列的第 4 篇,你可能錯過了前面的篇章,可以在這里找到: 偽類與偽元素的區別及實戰 如何實現一個圣杯布局? 今日頭條 面試題和思...
摘要:首先,我先去上搜索了的定義運算符創建一個用戶定義的對象類型的實例或具有構造函數的內置對象的實例。 今天看到一道面試題,如下,問: 實例化 Person 過程中,Person返回什么(或者 p 等于什么)? function Person(name) { this.name = name return name; } let p = new Person(Tom); 說實...
摘要:直接開始題目是厲害了說句實話開發中誰寫成這樣保證會被打死。不過面試就是面試,有面試官的考量點。官方是這么說的。結果完美,不過小姐姐的意思是數組的方法會自動觸發數組的。 直接開始題目是 if(a==1 && a==2 && a==3){ alert(厲害了) } 說句實話開發中誰寫成這樣保證會被打死。 不過面試就是面試,有面試官的考量點。 我理解的點有兩個 1、隱式類型轉換 先說...
閱讀 882·2021-11-23 09:51
閱讀 1088·2021-11-15 17:57
閱讀 1667·2021-09-22 15:24
閱讀 812·2021-09-07 09:59
閱讀 2221·2019-08-29 15:10
閱讀 1849·2019-08-29 12:47
閱讀 751·2019-08-29 12:30
閱讀 3369·2019-08-26 13:51