摘要:首先來講講阮一峰的文章中的兩道思考題。環(huán)境記錄包含包含了函數(shù)內(nèi)部聲明的局部變量和參數(shù)變量,外部引用指向了外部函數(shù)對象的上下文執(zhí)行場景。
本文最主要講講JavaScript閉包和this綁定相關(guān)的我的小發(fā)現(xiàn),鑒于這方面的基礎(chǔ)知識已經(jīng)有很多很好的文章講過了,所以基本的就不講了,推薦看看酷殼上的理解Javascript的閉包和阮一峰的學(xué)習(xí)Javascript閉包(Closure),寫的都非常好。
首先來講講阮一峰的文章中的兩道思考題。
代碼片段一
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; }; } }; alert(object.getNameFunc()());
這段代碼最后輸出的是
The Window
原因在同一片文章的評論中已經(jīng)有人指出了
George Wing 說:
上面本人說得不太正確。
this的指向是由它所在函數(shù)調(diào)用的上下文決定的,而不是由它所在函數(shù)定義的上下文決定的。
對于最后返回的這個匿名函數(shù)
function(){ return this.name; };
它是作為一個獨(dú)立的函數(shù)返回的,它的調(diào)用域是在全局上,所以會輸出全局變量name。
代碼片段二
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ var that = this; return function(){ return that.name; }; } }; alert(object.getNameFunc()());
代碼片段二最后輸出的是
My Object
這里就要考慮var that = this;這句的作用了,由于getNameFunc是object內(nèi)部的函數(shù),所以它調(diào)用的上下文this保存的是object的信息,將其保存到that變量,這樣作為內(nèi)部函數(shù)的匿名函數(shù)就可以直接訪問了。
可以注意到的是,阮一峰文章中的代碼,都是將通過一個JSON對象來訪問內(nèi)部的函數(shù),這樣其實(shí)有些地方還不夠清晰,畢竟不怎么嚴(yán)格地說,閉包就是函數(shù)內(nèi)部的函數(shù),所以我借用CoolShell上的文章中的例子來進(jìn)一步說明。
代碼片段三
function greeting(name) { var text = "Hello " + name; // local variable // 每次調(diào)用時,產(chǎn)生閉包,并返回內(nèi)部函數(shù)對象給調(diào)用者 return function() { alert(text); } } var sayHello=greeting("Closure"); sayHello() // 通過閉包訪問到了局部變量text
這段代碼輸出
Hello Closure
看上去好像很好理解,接下來看代碼片段四:
代碼片段四
var text = "findingsea"; function greeting(name) { var text = "Hello " + name; // local variable // 每次調(diào)用時,產(chǎn)生閉包,并返回內(nèi)部函數(shù)對象給調(diào)用者 return function() { alert(this.text); } } var sayHello=greeting("Closure"); sayHello() // 通過閉包訪問到了局部變量text
這段代碼輸出
findingsea
這是為什么呢?
針對代碼片段三,CoolShell上的原文有解釋:
文法環(huán)境中用于解析函數(shù)執(zhí)行過程使用到的變量標(biāo)識符。我們可以將文法環(huán)境想象成一個對象,該對象包含了兩個重要組件,環(huán)境記錄(Enviroment Recode),和外部引用(指針)。環(huán)境記錄包含包含了函數(shù)內(nèi)部聲明的局部變量和參數(shù)變量,外部引用指向了外部函數(shù)對象的上下文執(zhí)行場景。全局的上下文場景中此引用值為NULL。這樣的數(shù)據(jù)結(jié)構(gòu)就構(gòu)成了一個單向的鏈表,每個引用都指向外層的上下文場景。
針對代碼片段四,就是我們之前講過的,this保存是調(diào)用環(huán)境下的上下文內(nèi)容,所以會輸出全局的text。
總結(jié)本文想說明的是以下兩點(diǎn):
在函數(shù)閉包中,不使用this對變量進(jìn)行訪問時,函數(shù)會通過文法環(huán)境中的外部引用(指針),一級級地往上找(單向鏈表),直到找到(或者最終找不到)對應(yīng)的變量。這個結(jié)構(gòu)是在函數(shù)定義的時候就決定了的。
在函數(shù)閉包中,使用this對變量進(jìn)行訪問時,和絕大多數(shù)語言不同,JavaScript的this保存的是調(diào)用環(huán)境的上下文,也就是說this中的內(nèi)容是在調(diào)用的時候決定的,所以訪問到的是當(dāng)前環(huán)境下的對應(yīng)變量,并不會像前一種情況一樣進(jìn)行逐級查找。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/87555.html
摘要:最近剛剛看完了你不知道的上卷,對有了更進(jìn)一步的了解。你不知道的上卷由兩部分組成,第一部分是作用域和閉包,第二部分是和對象原型。附錄詞法這一章并沒有說明機(jī)制,只是介紹了中的箭頭函數(shù)引入的行為詞法。第章混合對象類類理論類的機(jī)制類的繼承混入。 最近剛剛看完了《你不知道的 JavaScript》上卷,對 JavaScript 有了更進(jìn)一步的了解。 《你不知道的 JavaScript》上卷由兩部...
摘要:全局的函數(shù)第個對象第個對象作為構(gòu)造器進(jìn)行調(diào)用也就是利用運(yùn)算符進(jìn)行調(diào)用。與操作的共同使用只有通過操作產(chǎn)生的對象,可以使用構(gòu)造器函數(shù)原型鏈上的內(nèi)容,否則對象只能使用自己原型鏈上的內(nèi)容。 今天這個話題是因?yàn)檫@幾天看了《JavaScript忍者秘籍》,感覺這本書把這幾個內(nèi)容講的蠻透徹了,特撰本文,以便日后翻閱。(應(yīng)該都會以知識點(diǎn)的形式給出吧。) 函數(shù) 1.【基本類型】 JavaScript中函...
摘要:被調(diào)用的函數(shù)一定是在當(dāng)前函數(shù)體內(nèi)被調(diào)用的。所以,當(dāng)前函數(shù)并沒有暫停,只是交出了控制權(quán)而已。它代表函數(shù)運(yùn)行時,自動生成的一個內(nèi)部對象,只能在函數(shù)內(nèi)部使用。 函數(shù) 調(diào)用一個函數(shù)會暫停當(dāng)前函數(shù)的執(zhí)行,傳遞控制權(quán)和參數(shù)給新調(diào)用的函數(shù),除了聲明時傳遞的形式參數(shù)外,每個函數(shù)還會接受兩個附加的參數(shù): this和arguement. 其實(shí)在讀到這句話的的時候,我產(chǎn)生了兩個莫名其妙的疑問1.調(diào)用一個函數(shù)...
摘要:在代碼執(zhí)行時,對應(yīng)的作用域鏈常常是保持靜態(tài)的。當(dāng)語句執(zhí)行完畢后,會把作用域鏈恢復(fù)到原始狀態(tài)。在全局作用域中創(chuàng)建的函數(shù),其作用域鏈會自動成為全局作用域中的一員。 列表項(xiàng)目 前言 學(xué)習(xí)了javascript已經(jīng)很久了,關(guān)于這個語言中的這兩個特性也是早已耳熟能詳,但是在實(shí)際的使用的過程中或者是遇到相關(guān)的問題的時候,還是不能很好的解決。因此我覺得很有必要深入的學(xué)習(xí)并且記錄這個問題,以便在今后的...
摘要:閉包的學(xué)術(shù)定義先來參考下各大權(quán)威對閉包的學(xué)術(shù)定義百科閉包,又稱詞法閉包或函數(shù)閉包,是引用了自由變量的函數(shù)。所以,有另一種說法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實(shí)體。 前言 上一章講解了閉包的底層實(shí)現(xiàn)細(xì)節(jié),我想大家對閉包的概念應(yīng)該也有了個大概印象,但是真要用簡短的幾句話來說清楚,這還真不是件容易的事。這里我們就來總結(jié)提煉下閉包的概念,以應(yīng)付那些非專人士的心血來潮。 閉包的學(xué)術(shù)...
閱讀 3750·2021-11-15 11:37
閱讀 2339·2021-09-24 10:39
閱讀 2523·2021-07-25 21:37
閱讀 1507·2019-08-30 15:56
閱讀 2603·2019-08-30 15:55
閱讀 987·2019-08-30 15:54
閱讀 2146·2019-08-30 14:21
閱讀 875·2019-08-30 11:24