摘要:發(fā)現(xiàn)指向的是,也就是說,在函數(shù)內(nèi)部實(shí)現(xiàn)的閉包函數(shù)已經(jīng)被轉(zhuǎn)變成了全局函數(shù),存儲(chǔ)到了內(nèi)存中。閉包同樣可以模擬面向?qū)ο蟮乃接凶兞康姆椒ê妥兞康氖褂煤瞳@取。
https://developer.mozilla.org...首先引用來自官網(wǎng)文檔的定義:
closure is the combination of a function and the lexical environment within which that function was declared.
閉包是一個(gè)函數(shù)和其內(nèi)部公開變量的環(huán)境的集合.
簡單而言, 閉包 = 函數(shù) + 環(huán)境
第一個(gè)閉包的例子function init() { var name = "Mozilla"; // name is a local variable created by init function displayName() { // displayName() is the inner function, a closure alert(name); // use variable declared in the parent function } displayName(); } init(); because inner functions have access to the variables of outer functions, displayName() can access the variable name declared in the parent function, init().
其實(shí)這個(gè)栗子很簡單,displayName()就是init()內(nèi)部的閉包函數(shù),而為啥在displayName內(nèi)部可以調(diào)用到外部定義的變量 name 呢,因?yàn)?strong>js內(nèi)部函數(shù)有獲取外部函數(shù)中變量的權(quán)限。
第二個(gè)栗子var data = [ {"key":0}, {"key":1}, {"key":2} ]; function showKey() { for(var i=0;i上面這個(gè)例子可以正確輸出 10 11 12 嗎?
答案是:并不能,并且還會(huì)報(bào)語法錯(cuò)誤....console.log(i); 發(fā)現(xiàn)i輸出了3次3,也就是說,在setTimeout 1000毫秒之后,執(zhí)行閉包函數(shù)的時(shí)候,for循環(huán)已經(jīng)執(zhí)行結(jié)束了,i是固定值,并沒有實(shí)現(xiàn)我們期望的效果。
console.log(this); 發(fā)現(xiàn) this 指向的是 Window,也就是說,在函數(shù)內(nèi)部實(shí)現(xiàn)的閉包函數(shù)已經(jīng)被轉(zhuǎn)變成了全局函數(shù),存儲(chǔ)到了內(nèi)存中。
所以需要再定義一個(gè)執(zhí)行函數(shù)
var data = [ {"key":0}, {"key":1}, {"key":2} ]; function showKey() { var f1 = function(n){ data[i].key = data[i].key + 10; console.log(data[i].key) } for(var i=0;i第三個(gè)閉包的例子-柯里化(currying) function makeAdder(x) { return function(y) { return function(z) { return x + y + z; } }; } console.log(makeAdder(1)(2)(3)); // 6 // function factory it creates functions which can add a specific value to their argument var add5 = makeAdder(5); console.log(add5(1)(2)); // 8 console.log(add5(4)(5)); // 14這種返回function的形式就是柯里化,作用是 makeAdder 可以作為一個(gè) function factory來使用。
第四個(gè)閉包的例子 - practicle closure閉包的適用場景:當(dāng)你想要通過一個(gè)function來操作它關(guān)聯(lián)的數(shù)據(jù)時(shí),閉包是很有用的,這種使用方法是類似面向?qū)ο蟮摹?/p>
閉包同樣可以模擬面向?qū)ο蟮乃接凶兞康姆椒ê妥兞康氖褂煤瞳@取。
var counter = (function() { // private variable var privateCounter = 0; // private function function changeBy(val) { privateCounter += val; } return { changeValue: function(val) { changeBy(val); }, value: function() { return privateCounter; } }; })(); console.log(counter.value()); // logs 0 // 實(shí)現(xiàn)了內(nèi)部屬性的獲取 counter.changeValue(2);// 實(shí)現(xiàn)了內(nèi)部的changeBy()方法 counter.changeValue(10); console.log(counter.value()); // logs 12 counter.changeValue(-5); console.log(counter.value()); // logs 7counter對外暴露的方法就是 counter.changeValue, counter.value,而內(nèi)部屬性 privateCounter 和 內(nèi)部方法 changeBy 被隔離開了,只能通過外部方法來調(diào)用。
同時(shí)我們也可以定義多個(gè) counter,其內(nèi)部屬性也是相互隔離的。
var makeCounter = function() { var privateCounter = 0; function changeBy(val) { privateCounter += val; } return { increment: function() { changeBy(1); }, decrement: function() { changeBy(-1); }, value: function() { return privateCounter; } } }; var counter1 = makeCounter(); var counter2 = makeCounter(); alert(counter1.value()); /* Alerts 0 */ counter1.increment(); counter1.increment(); alert(counter1.value()); /* Alerts 2 */ counter1.decrement(); alert(counter1.value()); /* Alerts 1 */ alert(counter2.value()); /* Alerts 0 */
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/94312.html
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。異步編程入門的全稱是前端經(jīng)典面試題從輸入到頁面加載發(fā)生了什么這是一篇開發(fā)的科普類文章,涉及到優(yōu)化等多個(gè)方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結(jié)思考,循序漸進(jìn)的理解 TypeScript。 網(wǎng)絡(luò)基礎(chǔ)知識之 HTTP 協(xié)議 詳細(xì)介紹 HTT...
摘要:注此讀書筆記只記錄本人原先不太理解的內(nèi)容經(jīng)過閱讀你不知道的后的理解。作用域及閉包基礎(chǔ),代碼運(yùn)行的幕后工作者引擎及編譯器。 注:此讀書筆記只記錄本人原先不太理解的內(nèi)容經(jīng)過閱讀《你不知道的JS》后的理解。 作用域及閉包基礎(chǔ),JS代碼運(yùn)行的幕后工作者:引擎及編譯器。引擎負(fù)責(zé)JS程序的編譯及執(zhí)行,編譯器負(fù)責(zé)詞法分析和代碼生成。那么作用域就像一個(gè)容器,引擎及編譯器都從這里提取東西。 ...
摘要:但是,必須強(qiáng)調(diào),閉包是一個(gè)運(yùn)行期概念。通過原型鏈可以實(shí)現(xiàn)繼承,而與閉包相關(guān)的就是作用域鏈。常理來說,一個(gè)函數(shù)執(zhí)行完畢,其執(zhí)行環(huán)境的作用域鏈會(huì)被銷毀。所以此時(shí),的作用域鏈雖然銷毀了,但是其活動(dòng)對象仍在內(nèi)存中。 學(xué)習(xí)Javascript閉包(Closure)javascript的閉包JavaScript 閉包深入理解(closure)理解 Javascript 的閉包JavaScript ...
摘要:什么是閉包定義我所理解的閉包就是,即使外部函數(shù)已經(jīng)運(yùn)行完畢,內(nèi)部函數(shù)仍能訪問外部函數(shù)的作用域中的變量。閉包的應(yīng)用場景私有變量模塊需求只能通過函數(shù)提供的方法訪問函數(shù)內(nèi)部的變量隱藏。為什么閉包很重要參考資料征服面試什么是閉包 1. 什么是閉包 MDN定義:Closures are functions that refer to independent (free) variables (v...
摘要:在一個(gè)閉包環(huán)境內(nèi)修改變量值,不會(huì)影響另一個(gè)閉包中的變量。直到看到函數(shù)閉包閉包這篇文章的代碼一部分,終于明白其中的邏輯了。 閉包 閉包定義:指擁有多個(gè)變量和綁定了這些變量的環(huán)境的表達(dá)式(通常是一個(gè)函數(shù)),因而這些變量也是該表達(dá)式的一部分。函數(shù)內(nèi)部可以直接讀取全局變量。函數(shù)內(nèi)部變量無法在函數(shù)外部訪問。函數(shù)內(nèi)部聲明要用var或者let聲明,不然會(huì)變成全局變量鏈?zhǔn)阶饔糜颍鹤訉ο髸?huì)一級級向上尋找...
閱讀 799·2021-11-12 10:36
閱讀 3382·2021-09-08 10:44
閱讀 2748·2019-08-30 11:08
閱讀 1407·2019-08-29 16:12
閱讀 2677·2019-08-29 12:24
閱讀 901·2019-08-26 10:14
閱讀 686·2019-08-23 18:32
閱讀 1176·2019-08-23 17:52