摘要:理解了這句話,我們就可以來看閉包了閉包前面說過,函數(shù)可以訪問函數(shù)作用域鏈中的變量,但如果我們想在函數(shù)外訪問函數(shù)內(nèi)卻不行了。
不管是閉包還是this關(guān)鍵字,都是困擾JS初學者的比較難懂的東西,如果你對它們的認識還不足夠清晰,那么現(xiàn)在就一起把它們掌握掉。還是那句話,我們從最基本的開始,建立起一個非常清晰的知識結(jié)構(gòu),好了,開始吧 ?
閉包當然我們今天說的是javascript里的閉包。要學習閉包,首先需要明白函數(shù)和變量,其次要知道變量和函數(shù)的一些特性。來復習一下:
變量變量是那些會變化的東西(就這么簡單),變量有一個值,我們能改變這個值。我們先聲明一個變量名,然后對這個變量賦值,就創(chuàng)建了一個變量。變量分按作用域(這個很重要后面會講到)為全局變量和局部變量。
函數(shù)我們最初學習的是通過函數(shù)聲明來創(chuàng)建一個函數(shù),即首先是 function 關(guān)鍵字,然后是函數(shù)的名字,這就是指定函數(shù)名的方式。另一個方式叫做函數(shù)表達式,最常見的形式是這樣的:
var functionName = function(arg0, arg1, arg2){ //函數(shù)體 };
我們創(chuàng)建的這個函數(shù)叫做匿名函數(shù),因為 function 關(guān)鍵字后面沒有標識符,沒有名字嘛。
結(jié)合函數(shù)和作用域,我們來小小地總結(jié)一下:函數(shù)內(nèi)可以讀取函數(shù)外的變量,而函數(shù)外卻讀取不了函數(shù)內(nèi)部的變量(局部變量)。理解了這句話,我們就可以來看閉包了:
前面說過,函數(shù)可以訪問函數(shù)作用域鏈中的變量,但如果我們想在函數(shù)外訪問函數(shù)內(nèi)卻不行了。比如這個例子:
function myfunction(){ var num=21; } alert(num); // error
眼前就有一個變量,尷尬的是我們調(diào)用不了。
想想辦法:根據(jù)函數(shù)可以訪問函數(shù)作用域鏈中的變量這句話,如果我們在函數(shù)內(nèi)再定義一個函數(shù),讓這個新函數(shù)訪問舊函數(shù)里的變量,然后返回這個函數(shù),然后直接運行那個舊函數(shù)不就可以了嗎!
function myfunction(){ var num=21; function newfunction(){ alert(num); } return newfunction; } var result=myfunction(); result(); // 21
沒有任何問題,在函數(shù)外面成功訪問到了num變量。
恭喜你,你剛剛創(chuàng)建了一個閉包。。。是的,這個就是閉包。閉包就是指有權(quán)訪問另一個函數(shù)作用域中的變量的函數(shù)。創(chuàng)建閉包的常見方式,就是在一個函數(shù)內(nèi)部創(chuàng)建另一個函數(shù)。
明白了閉包,再來看為什么可以把閉包和this放一起理解:
this關(guān)鍵字首先你需要記住的是:this的對象是運行時基于函數(shù)的執(zhí)行環(huán)境綁定的,它的指向完全取決于函數(shù)的調(diào)用方式
不多說來看兩個經(jīng)典例子:
第1個例子
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; }; } }; alert(object.getNameFunc()()); //"The Window"(在非嚴格模式下)
第2個例子
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ var that = this; return function(){ return that.name; }; } }; alert(object.getNameFunc()()); //"My Object"
關(guān)于這兩個例子,我個人感覺《Javascript高級程序設(shè)計》這本書里講得不夠明確。我的理解是第1個例子里是在全局環(huán)境中調(diào)用了這個函數(shù),所以this關(guān)鍵字最終指向了全局對象The Window,從而利用閉包在全局環(huán)境中調(diào)用了The Window;第2個例子不同,它返回的是that的name,而this對象被賦值給了that變量,就是說this對象和that捆綁在了一起,那么在調(diào)用這個方法時相當于在object里利用閉包去尋找最終變量(that是引用著object的),所以只能找到My Object變量。
這兩個例子非常好,怎么個好法呢。它們完整解釋(展現(xiàn))了閉包的作用機理或者說過程,同時又證明了this關(guān)鍵字在函數(shù)被不同的環(huán)境調(diào)用時的指向是不一樣的。
怎么樣,看到這里是不是徹底明白了閉包和this關(guān)鍵字呢。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/88488.html
摘要:是完全的面向?qū)ο笳Z言,它們通過類的形式組織函數(shù)和變量,使之不能脫離對象存在。而在基于原型的面向?qū)ο蠓绞街?,對象則是依靠構(gòu)造器利用原型構(gòu)造出來的。 JavaScript 函數(shù)式腳本語言特性以及其看似隨意的編寫風格,導致長期以來人們對這一門語言的誤解,即認為 JavaScript 不是一門面向?qū)ο蟮恼Z言,或者只是部分具備一些面向?qū)ο蟮奶卣?。本文將回歸面向?qū)ο蟊疽?,從對語言感悟的角度闡述為什...
摘要:忍者級別的函數(shù)操作對于什么是匿名函數(shù),這里就不做過多介紹了。我們需要知道的是,對于而言,匿名函數(shù)是一個很重要且具有邏輯性的特性。通常,匿名函數(shù)的使用情況是創(chuàng)建一個供以后使用的函數(shù)。 JS 中的遞歸 遞歸, 遞歸基礎(chǔ), 斐波那契數(shù)列, 使用遞歸方式深拷貝, 自定義事件添加 這一次,徹底弄懂 JavaScript 執(zhí)行機制 本文的目的就是要保證你徹底弄懂javascript的執(zhí)行機制,如果...
摘要:函數(shù)式編程前端掘金引言面向?qū)ο缶幊桃恢币詠矶际侵械闹鲗Х妒?。函?shù)式編程是一種強調(diào)減少對程序外部狀態(tài)產(chǎn)生改變的方式。 JavaScript 函數(shù)式編程 - 前端 - 掘金引言 面向?qū)ο缶幊桃恢币詠矶际荍avaScript中的主導范式。JavaScript作為一門多范式編程語言,然而,近幾年,函數(shù)式編程越來越多得受到開發(fā)者的青睞。函數(shù)式編程是一種強調(diào)減少對程序外部狀態(tài)產(chǎn)生改變的方式。因此,...
摘要:之前一篇文章我們詳細說明了變量對象,而這里,我們將詳細說明作用域鏈。而的作用域鏈,則同時包含了這三個變量對象,所以的執(zhí)行上下文可如下表示。下圖展示了閉包的作用域鏈。其中為當前的函數(shù)調(diào)用棧,為當前正在被執(zhí)行的函數(shù)的作用域鏈,為當前的局部變量。 showImg(https://segmentfault.com/img/remote/1460000008329355);初學JavaScrip...
摘要:設(shè)計模式是以面向?qū)ο缶幊虨榛A(chǔ)的,的面向?qū)ο缶幊毯蛡鹘y(tǒng)的的面向?qū)ο缶幊逃行┎顒e,這讓我一開始接觸的時候感到十分痛苦,但是這只能靠自己慢慢積累慢慢思考。想繼續(xù)了解設(shè)計模式必須要先搞懂面向?qū)ο缶幊蹋駝t只會讓你自己更痛苦。 JavaScript 中的構(gòu)造函數(shù) 學習總結(jié)。知識只有分享才有存在的意義。 是時候替換你的 for 循環(huán)大法了~ 《小分享》JavaScript中數(shù)組的那些迭代方法~ ...
閱讀 2120·2021-11-24 09:39
閱讀 1503·2019-08-30 15:44
閱讀 1954·2019-08-29 17:06
閱讀 3406·2019-08-29 16:32
閱讀 3552·2019-08-29 16:26
閱讀 2662·2019-08-29 15:35
閱讀 3033·2019-08-29 12:50
閱讀 1646·2019-08-29 11:15