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