摘要:補充我弄明白了上面的問題,重點在于函數的作用域,函數中定義的變量之前我說沒用,為什么沒用是因為函數是定義在函數下的,所以的作用域鏈是這樣的因為函數是這樣定義的,所以函數定義了變量,所以中的賦值給了函數的參數。
在阮一峰老師的微博上看到這樣一道題:
javascriptfunction a(x, y) { y = function(){ x = 2; }; return function() { var x = 3; y(); console.log(x); }.apply(this, arguments); } a();
問:輸出是多少?為什么?
我想到了答案,并且驗證正確,小興奮,在這里寫下解題思路:
這道題的迷惑很多
return其實沒用,代碼可以變成
javascriptfunction a(x, y) { y = function(){ x = 2; }; (function() { var x = 3; y(); console.log(x); }).apply(this, arguments); } a();
執行a();其實是執行
javascriptfunction() { var x = 3; y(); console.log(x); }apply(this, arguments);
其中:1. this是跟作用域(瀏覽器環境下是window,node環境下是global),因為是在跟作用域下執行的a();。 2. arguments是空,因為a();沒有參數。
y();沒用。因為y定因為函數首先定義了var x = 3;,所以console.log(x)就是3。因為作用域優先級是從內向外由高到低的,所以在這里var x = 3;的優先級是最高的,y();中不管定義的什么,都不會影響到x。所以之前分析了那么多,其實都沒用啊!做題時讀代碼,順序要從內部到外部(僅限于做題)~
問題:這道題如果將輸出改成console.log(this.x),答案會是什么? 我認為是2,可是結果確實undefined,這是為什么呢? 目前我還沒搞明白,求解。
javascriptfunction a(x, y) { y = function(){ x = 2; }; return function() { var x = 3; y(); console.log(this.x); }.apply(this, arguments); } a();補充
我弄明白了上面的問題,重點在于:1. 函數y的作用域,2. 函數a中定義的變量
之前我說y();沒用,為什么沒用?是因為函數y是定義在函數a下的,所以y的作用域鏈是這樣的:
window
a
y
因為函數a是這樣定義的:function a(x, y),所以函數a定義了變量x,所以y中的x = 2;賦值給了函數a的x參數。并沒有賦值給window作用域下的x,而console.log(this.x);中this指的是window,所以輸出為undefined。
如果將函數a的參數去掉,題目變成:
javascriptfunction a() { y = function(){ x = 2; }; return function() { var x = 3; y(); console.log(this.x); }.apply(this, arguments); } a();
這樣函數a中就沒有x這個變量了,所以函數y中的x = 2;就會賦值給跟作用域下的x,所以console.log(this.x);的輸出就會變成2。
再將題目改一下,如果將函數y()定義在return 的匿名函數里面,題目變為:
javascriptfunction a(x, y) { return function() { y = function(){ x = 2; }; var x = 3; y(); console.log(x); }.apply(this, arguments); } a();
問console.log(x)會輸出什么? 答案是2,因為此時y的作用域鏈是這樣的:
window
a
匿名函數
y
因為匿名函數中定義了var x = 3;,所以函數y中的x = 2;就會修改匿名函數中的x的值,所以console.log(x)輸出變成了3,
弄明白這道題的每一處細節,對理解javascript語言的作用域很有幫助。雖然這道題對編程本身沒有什么意義。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/91478.html
摘要:關于作用域實現的描述任何執行上下文時刻的作用域,都是由作用域鏈來實現的。在一個函數被定義的時候,會將它此時的作用域鏈鏈接到這個函數對象的屬性。參考資料鳥哥作用域原理理解作用域和作用域鏈阮一峰老師微博上的關于作用域的一道題 javascript作用域原理學習 在每次調用一個函數的時候,就會進入一個函數內的作用域,當從函數返回 以后,就會返回調用前的作用域。 ECMA262關于作...
摘要:全局環境調用函數的對象實際為,所以函數內的指向構造函數通過構造函造函數生成了一個新對象,指向這個新對象。學習前端一個月,上一周面試了大概多家,收獲的卻是寥寥。為了效率,前端各方面的內容都有涉獵,深度卻相當不足,面試時暴露各種問題。 最近面試了不少家,苦于前端經驗薄弱,被各種血虐。做了不少家面試題,把各種不會的回來再做一遍,作為經驗總結吧。 1.如何最優性能去重一個數組? 方法有好多,比...
閱讀 1646·2023-04-25 20:36
閱讀 2065·2021-09-02 15:11
閱讀 1206·2021-08-27 13:13
閱讀 2659·2019-08-30 15:52
閱讀 4689·2019-08-29 17:13
閱讀 1008·2019-08-29 11:09
閱讀 1498·2019-08-26 11:51
閱讀 843·2019-08-26 10:56