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