這個問題的答案是社區的努力。編輯現有答案以改善此職位。它目前不接受新的答案或互動。 您將如何向了解了閉包本身的概念(例如函數,變量等)的人解釋JavaScript閉包,但卻不了解閉包本身? 我已經在Wikipedia上看到了Scheme示例,但是不幸的是它沒有幫助。
1個 2 3 下一個 閉包是以下各項的配對: 一個功能,以及 對函數外部範圍的引用(詞法環境) 詞法環境是每個執行上下文(堆棧框架)的一部分,並且是標識符(即局部變量名稱)和值之間的映射。 JavaScript中的每個函數都對其外部詞彙環境保持引用。此引用用於配置調用函數時創建的執行上下文。此引用使函數內部的代碼可以“查看”在函數外部聲明的變量,而不管調用函數的時間和位置。 如果一個函數被一個函數調用,而另一個函數又調用了另一個函數,則將創建對外部詞彙環境的引用鏈。該鏈稱為作用域鏈。 在以下代碼中,inner與調用foo時創建的執行上下文的詞法環境形成一個閉包,從而對變量secret進行關閉: 函數foo(){ const secret = Math.trunc(Math.random()* 100) 返回函數inner(){ console.log(`秘密號是$ {secret}。`) } } const f = foo()//無法從外部`foo`直接訪問`secret` f()//檢索“秘密”的唯一方法是調用“ f” 換句話說:在JavaScript中,函數帶有對私有“狀態框”的引用,只有它們(以及在相同詞法環境中聲明的任何其他函數)可以訪問。該狀態框對於函數的調用者是不可見的,從而為數據隱藏和封裝提供了一種出色的機制。 請記住:JavaScript中的函數可以像變量一樣傳遞(一流的函數),這意味著功能和狀態對可以在程序中傳遞:類似於您在C ++中傳遞類的實例的方式。 如果JavaScript沒有閉包,則必須在函數之間顯式傳遞更多狀態,從而使參數列表更長,代碼更嘈雜。 因此,如果您希望函數始終有權訪問私有狀態,則可以使用閉包。 ...而且我們經常想將狀態與函數關聯。例如,在Java或C ++中,當您將私有實例變量和方法添加到類時,您正在將狀態與功能相關聯。 在C語言和大多數其他常見語言中,函數返回後,所有本地變量將不再可訪問,因為堆棧框架被破壞了。在JavaScript中,如果在另一個函數中聲明一個函數,則外部函數從其返回後仍可訪問。這樣,在上面的代碼中,機密在從foo返回後仍可用於函數對象內部。 閉包的使用 每當需要與函數關聯的私有狀態時,閉包都是有用的。這是一個非常常見的情況-請記住:JavaScript直到2015年才使用類語法,並且仍然沒有私有字段語法。封閉件可滿足此需求。 私有實例變量 在以下代碼中,函數toString關閉了汽車的詳細信息。 功能Car(製造商,型號,年份,顏色){ 返回{ toString(){ 返回`$ {manufacturer} $ {model}($ {year},$ {color})` } } } const car = new Car('Aston Martin','V8 Vantage','2012','Quantum Silver') console.log(car.toString()) 功能編程 在以下代碼中,函數inner關閉fn和args。 函數curry(fn){ const args = [] 返回函數inner(arg){ if(args.length === fn.length)返回fn(... args) args.push(arg) 返回內部 } } 函數add(a,b){ 返回a + b } const curriedAdd =咖哩(添加) console.log(curriedAdd(2)(3)())// 5 面向事件的程序設計 在以下代碼中,函數onClick關閉變量Background_COLOR。 const $ = document.querySelector.bind(document) const Background_COLOR ='rgba(200,200,242,1)' 函數onClick(){ $('body')。style.background =背景顏色 } $('button')。addEventListener('click',onClick)