閉包是JavaScript中重要的特性,最大的功能在於保存函數運作過程中的資訊。在JavaScript中,閉包的諸多特性源自於函數呼叫過程中的作用域鏈上。
函數呼叫物件與變數的作用域鏈
對於JavaScript中的每一次函數調用,JavaScript都會創建一個局部物件以儲存在該函數中定義的局部變數;如果在該函數內部還有一個嵌套定義的函數(nested function),那麼JavaScript會在已經定義的局部物件之上再定義一個嵌套局部物件。對於一個函數,其內部有多少層的巢狀函數定義,也就有多少層的巢狀局部物件。這個局部物件稱為“函數呼叫物件”(ECMAScript 3中的“call object”,ECMAScript 5中改名為“declarative environment record”,但個人認為還是ECMAScript 3中的名稱更容易理解一些)。以下面的函數呼叫為例:
function f(x){
var a = 10;
return a*x;
}
console.log(f(6));//60
在這個簡單的例子中,當呼叫f()函數時,JavaScript會建立一個f()函數的呼叫物件(姑且稱為f_invokeObj),在f_invokeObj物件內部有兩個屬性:a和x;運行f()時,a值為10而x值為6,因此最後的回傳結果為60。圖示如下:
當存在函數巢狀時,JavaScript將建立多個函數呼叫物件:
function f(x){
var a = 10;
return a*g(x);
function g(b){
return b*b;
}
}
console.log(f(6));//360
在這個範例中,當呼叫f()函數時,JavaScript會建立一個f()函數的呼叫物件(f_invokeObj),其內部有兩個屬性a和x,a值為10而x值為6;執行f ()時,JavaScript會對f()函數中的g()函數進行解析定義,並建立g()的呼叫物件(g_invokeObj),其內部有一個屬性b,b值與傳入參數x相同為6 ,因此最後的回傳結果為360。圖示如下:
可以看到,函數呼叫物件形成了一條鏈。當內嵌函數g()運行,需要取得變數值的時候,會從最近的函數呼叫物件開始進行搜索,如果無法搜尋到,則沿函數呼叫物件鏈在更遠的呼叫物件中進行搜尋,此即所謂的「變數的作用域鏈」。如果兩個函數呼叫物件中出現相同的變量,則函數會取離自己最近的那個呼叫物件中的變數值:
function f(x){
var a = 10;
return a*g(x);
function g(b){
var a = 1;
return b*b*a;
}
}
console.log(f(6));//360, not 3600
在上面的例子中,g()函數的呼叫物件(g_invokeObj)和f()函數的呼叫物件(f_invokeObj)中均存在變數a且a的值不同,當執行g()函數時,在g()函數內部所使用的a值為1,而在g()函數外部所使用的a值則為10。圖示此時的函數呼叫物件鏈如下:
什麼是閉包?
在JavaScript中所有的函數(function)都是對象,而定義函數時都會產生對應的函數呼叫對象鏈,一次函數定義對應一個函數呼叫對象鏈。只要函數物件存在,對應的函數呼叫物件就存在;一旦某函數不再被使用,對應的函數呼叫物件就會被垃圾回收掉;而這種函數物件和函數呼叫物件鏈之間的一一組合,就稱為「閉包」。在上面f()函數和g()函數的例子中,就存在兩個閉包:f()函數物件和f_invokeObj物件組成了一個閉包,而g()函數物件和g_invokeObj-f_invokeObj物件鏈一起組成了第二個閉包。當g()函數執行完畢後,由於g()函數不再被使用,因此g()閉包被垃圾回收了;之後,當f()函數執行完畢後,由於同樣的原因,f()閉包包也被垃圾回收了。
從閉包的定義可以得出結論:所有的JavaScript函數在定義後都是閉包 – 因為所有的函數都是對象,所有的函數在執行後也都有其對應的呼叫對象鏈。
不過,令閉包真正發揮作用的是巢狀函數的情況。由於內嵌函數是在外部函數運行的時候才開始定義的,因此內嵌函數的閉包中所保存的變數值(尤其是外部函數的局部變數值)是這次運行過程中的值。只要內嵌函數物件依然存在,那麼其閉包就依然存在(閉包中的變數值不會發生任何改變),從而也就實現了保存函數運行過程的資訊這個目的。考慮以下這個例子:
var a = "outside";
function f(){
var a = "inside";
function g(){return a;}
return g;
}
var result = f();
console.log(result());//inside
在這個例子中,當運行f()函數時,g()函數被定義,同時建立了g()函數的閉包,g()閉包包含了g_invokeObj-f_invokeObj物件鏈,因此保存了f()函數執行過程中的變數a的值。當執行console.log()語句時,由於g函數物件仍然存在,因此g()閉包也依然存在;當執行這個仍然存在的g函數物件時,JavaScript會使用依然存在的g()閉包並從中取得變數a的值(“inside”)。

Python和JavaScript的主要區別在於類型系統和應用場景。 1.Python使用動態類型,適合科學計算和數據分析。 2.JavaScript採用弱類型,廣泛用於前端和全棧開發。兩者在異步編程和性能優化上各有優勢,選擇時應根據項目需求決定。

選擇Python還是JavaScript取決於項目類型:1)數據科學和自動化任務選擇Python;2)前端和全棧開發選擇JavaScript。 Python因其在數據處理和自動化方面的強大庫而備受青睞,而JavaScript則因其在網頁交互和全棧開發中的優勢而不可或缺。

Python和JavaScript各有優勢,選擇取決於項目需求和個人偏好。 1.Python易學,語法簡潔,適用於數據科學和後端開發,但執行速度較慢。 2.JavaScript在前端開發中無處不在,異步編程能力強,Node.js使其適用於全棧開發,但語法可能複雜且易出錯。

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

JavaScript框架的強大之處在於簡化開發、提升用戶體驗和應用性能。選擇框架時應考慮:1.項目規模和復雜度,2.團隊經驗,3.生態系統和社區支持。

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Dreamweaver Mac版
視覺化網頁開發工具

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

WebStorm Mac版
好用的JavaScript開發工具