摘要:的本質(zhì)問題其實(shí)就是詞法作用域的問題或者說是引擎如何在當(dāng)前作用域以及嵌套的子作用域中根據(jù)標(biāo)識符名稱進(jìn)行變量查找引擎查找標(biāo)識符位置的規(guī)則簡而言之就是作用域查找會在找到第一個匹配的標(biāo)識符時停止換句話說是作用域查找始終從運(yùn)行時所處的最內(nèi)部作用域開始
Closure的本質(zhì)問題其實(shí)就是詞法作用域的問題, 或者說是JavaScript引擎如何在當(dāng)前作用域以及嵌套的子作用域中根據(jù)標(biāo)識符名稱進(jìn)行變量查找.
JavaScript引擎查找標(biāo)識符位置的規(guī)則, 簡而言之, 就是:
作用域查找會在找到第一個匹配的標(biāo)識符時停止
換句話說是: 作用域查找始終從運(yùn)行時所處的最內(nèi)部作用域開始, 逐級向外或者說向上進(jìn)行, 知道遇見第一個匹配的標(biāo)識符為止
帶著以上的結(jié)論, 我們看看這個例子來驗(yàn)證一下:
function fun(n,o) { console.log(o) return { fun:function(m){ return fun(m,n); } }; } //Question 1 var a = fun(0); a.fun(1); a.fun(2); a.fun(3); //Question 2 var b = fun(0).fun(1).fun(2).fun(3); //Question 3 var c = fun(0).fun(1); c.fun(2); c.fun(3);
Question 1的答案和解釋
var a = fun(0); //undefined
a.fun(1); //0
a.fun(2); //0
a.fun(3); //0
Question 1.1
傳入n=0,并沒有傳入o, 所以是undefined。這個時候a是含有fun的object:
{ fun:function(m){ return fun(m,n); } }
Question 1.2
a包含的fun被trigger了, 傳入了n=1并且最終trigger了fun(m, n).
那么問題來了, m和n分別是什么?
m是剛剛傳進(jìn)來的1, 這個很簡單;
n只能根據(jù)作用域網(wǎng)上查找, 發(fā)現(xiàn)時上次傳進(jìn)來的一個形參, 它的值就應(yīng)該是上次傳進(jìn)來的0;
所以, 最終a.fun(1)是trigger了fun(1, 0), 最后的答案是0.
對于Question 1.3和1.4來說, 同理最終的答案也是0.
Question 2的答案和解釋
b = fun(0).fun(1).fun(2).fun(3)
//undefined
//0
//1
//2
根據(jù)Question 1.2的解釋 就很好理解這個答案了
Question 3的答案和解釋
var c = fun(0).fun(1); c.fun(2); c.fun(3);
//undefined
//0
//1
//1
根據(jù)Question 1.2的解釋 var c = fun(0).fun(1)會分別log出undefined和0
這個時候c應(yīng)該是含有fun的object:
{ fun:function(m){ return fun(m,n); } }
當(dāng)c.fun(2)的時候 其實(shí)也是trigger了fun(m, n).
m是當(dāng)前傳入的2. n由于沒有被傳入, 只能向外作用域?qū)ふ? 發(fā)現(xiàn)上次傳入的n且n=1.
所以最后log的值為1.
同理對于c.fun(3) 最后log的值也為1.
總結(jié)
通過理解JavaScript引擎向上查找作用域的規(guī)則 可以更好的讓我們理解Closure
Reference:
你不一定能做對的JavaScript閉包面試題
You Don"t Know JS: Scope & Closures
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/88418.html
溫馨提示:作者的爬坑記錄,對你等大神完全沒有價(jià)值,別在我這浪費(fèi)生命 這一切,源于阮大神博文學(xué)習(xí)Javascript閉包(Closure)- 阮一峰中的一道思考題 //問題1: var name = The Window; var object = { name : My Object, getNameFunc : function(){ return function(){ ...
摘要:當(dāng)初看這個解釋有點(diǎn)懵逼,理解成閉包就是函數(shù)中的函數(shù)了。里的閉包最近不滿足于只干前端的活,開始用起了。里的閉包最近在學(xué)習(xí)語言,讓我們來看一下語言里的閉包。在中,閉包特指將函數(shù)作為值返回的情況,被返回的函數(shù)引用了生成它的母函數(shù)中的變量。 本人開始接觸編程是從js開始的,當(dāng)時網(wǎng)上很多人說閉包是難點(diǎn),各種地方對閉包的解釋也是千奇百怪。如今開始接觸js以外的各種編程語言,發(fā)現(xiàn)不光是js,php、...
摘要:當(dāng)初看這個解釋有點(diǎn)懵逼,理解成閉包就是函數(shù)中的函數(shù)了。里的閉包最近不滿足于只干前端的活,開始用起了。里的閉包最近在學(xué)習(xí)語言,讓我們來看一下語言里的閉包。在中,閉包特指將函數(shù)作為值返回的情況,被返回的函數(shù)引用了生成它的母函數(shù)中的變量。 本人開始接觸編程是從js開始的,當(dāng)時網(wǎng)上很多人說閉包是難點(diǎn),各種地方對閉包的解釋也是千奇百怪。如今開始接觸js以外的各種編程語言,發(fā)現(xiàn)不光是js,php、...
摘要:譯者按在上一篇博客,我們通過實(shí)現(xiàn)一個計(jì)數(shù)器,了解了如何使用閉包,這篇博客將提供一些代碼示例,幫助大家理解閉包。然而,如果通過代碼示例去理解閉包,則簡單很多。不過,將閉包簡單地看做局部變量,理解起來會更加簡單。 - 譯者按: 在上一篇博客,我們通過實(shí)現(xiàn)一個計(jì)數(shù)器,了解了如何使用閉包(Closure),這篇博客將提供一些代碼示例,幫助大家理解閉包。 原文: JavaScript Clos...
摘要:但是閉包也不是什么復(fù)雜到不可理解的東西,簡而言之,閉包就是閉包就是函數(shù)的局部變量集合,只是這些局部變量在函數(shù)返回后會繼續(xù)存在??上У氖牵]有提供相關(guān)的成員和方法來訪問閉包中的局部變量。 (收藏自 技術(shù)狂) 前言:還是一篇入門文章。Javascript中有幾個非常重要的語言特性——對象、原型繼承、閉包。其中閉包 對于那些使用傳統(tǒng)靜態(tài)語言C/C++的程序員來說是一個新的語言特性。本文將...
閱讀 644·2021-08-17 10:15
閱讀 1742·2021-07-30 14:57
閱讀 1980·2019-08-30 15:55
閱讀 2823·2019-08-30 15:55
閱讀 2712·2019-08-30 15:44
閱讀 674·2019-08-30 14:13
閱讀 2388·2019-08-30 13:55
閱讀 2595·2019-08-26 13:56