摘要:一般來講,函數執行完畢后,局部活動對象就會被銷毀,內存中僅保存全局作用域,但是閉包的情況有所不同理解閉包的前提先理解另外兩個內容作用域鏈垃圾回收作用域鏈當代碼在執行過程中,會創建變量對象的一個作用域鏈。
閉包是javascript語言的一個難點,也是它的特色,很多高級應用都要依靠閉包來實現。個人的理解是:函數中嵌套函數。
閉包的定義及其優缺點閉包是指有權訪問另一個函數作用域中的變量的函數。創建閉包的常見方式,就是在一個函數內部創建另一個函數。
閉包的缺點是常駐內存,會增大內存的使用量,使用不當會造成內存泄漏。
應用閉包主要是為了:設計私有變量和方法。
一般來講,函數執行完畢后,局部活動對象就會被銷毀,內存中僅保存全局作用域,但是閉包的情況有所不同!
理解閉包的前提先理解另外兩個內容:作用域鏈、垃圾回收作用域鏈:當代碼在執行過程中,會創建變量對象的一個作用域鏈。作用域鏈的用途,是保證對執行環境有權訪問的所有變量和函數的有序訪問。
請看下面的一段代碼:
//全局環境中有一個變量color和一個函數changeColor() var color = "blue"; //changeColor()的局部環境中有一個anotherColor變量和swapColors()函數 function changeColor() { var anotherColor = "red"; //swapColors()環境中只有一個tempColor function swapColors() { var tempColor = anotherColor; anotherColor = color; color = tempColor; } swapColors(); } changeColor();
全局環境只能訪問到變量color
changeColor()局部環境也可以訪問color
swapColors()可以訪問其他兩個環境的所有變量,但是那兩個變量都無權訪問tempColor
總結:內部環境可以通過作用域鏈訪問所有的外部環境,但外部環境不能訪問內部環境中的任何變量和函數。每個環境都可以向上搜索作用域鏈,但任何環境都不能向下搜索作用域鏈而進入另一個執行環境。
垃圾回收原理
(1)javascript中如果一個對象不再被引用,那么這個對象就會被回收。
(2)如果兩個對象互相引用,而不再被第3者引用,那么這兩個互相引用的對象也會被回收。
嵌套函數的閉包
var f = function () { var a = 9999; function f1() { alert(a); } f1(); }; f();
函數嵌套時候,在f執行完成之后,變量a還要被f1這個內部嵌套的函數繼續使用,因此a不會被釋放。js解析器發現函數中嵌套了函數時,就會把函數中的變量和子函數的變量一起保存,構成了一個“閉包”。這些變量不會被內存回收器回收,只有當內部嵌套的函數不在執行后,才會被回收。
閉包的特性和使用閉包的好處閉包有三個特性:
1.函數嵌套函數
2.函數內部可以引用外部的參數和變量
3.參數和變量不會被垃圾回收機制回收
使用閉包的好處:
1.希望一個變量長期駐扎內存
2.避免全局變量污染
3.私有成員變量的存在
屬性
var person = function () { var name = "kimi"; this.getName = function () { return name; }; }; var p = new person(); alert(p.getName());
name屬性通過getName方法獲取到。
在循環中直接找到對應元素的索引
執行以上代碼發現點擊任何一個返回的都是4,這是因為賦值的時候,傳的i是對內存地址的引用,循環結束,i指向的就是4.
使用閉包改寫上面的代碼
閉包
每一次循環的時候,都把當前的i通過立即執行函數賦值。
變量的累加全局變量的累加
局部變量的累加
上述代碼沒有實現累加,改寫代碼如下:
模塊化代碼,減少全局變量的污染 this對象在閉包中使用this對象可能導致一些問題
代碼先創建了一個全局變量name,又創建了一個包含name屬性的對象。這個對象還包含一個getNameFunc()方法,返回一個匿名函數,匿名函數又返回一個this.name。調用object.getNameFunc()()返回一個字符串。內部函數搜索的時候只搜索到活動對象。
在定義匿名函數前,把this對象賦值給that變量,閉包也可以訪問這個變量。即使函數返回,仍然引用著object
學習了閉包也不知道到底哪里用到,到底有什么用。回答:(其實你寫的每一個js函數都是閉包,一個js函數的頂層作用域就是window對象,js的執行環境本身就是一個scope(瀏覽器的window/node的global),我們通常稱之為全局作用域。每個函數,不論多深,都可以認為是全局scope的子作用域,可以理解為閉包。)
本篇文章是自己學習過程中的總結,如有錯誤歡迎指正。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82442.html
摘要:當初看這個解釋有點懵逼,理解成閉包就是函數中的函數了。里的閉包最近不滿足于只干前端的活,開始用起了。里的閉包最近在學習語言,讓我們來看一下語言里的閉包。在中,閉包特指將函數作為值返回的情況,被返回的函數引用了生成它的母函數中的變量。 本人開始接觸編程是從js開始的,當時網上很多人說閉包是難點,各種地方對閉包的解釋也是千奇百怪。如今開始接觸js以外的各種編程語言,發現不光是js,php、...
摘要:當初看這個解釋有點懵逼,理解成閉包就是函數中的函數了。里的閉包最近不滿足于只干前端的活,開始用起了。里的閉包最近在學習語言,讓我們來看一下語言里的閉包。在中,閉包特指將函數作為值返回的情況,被返回的函數引用了生成它的母函數中的變量。 本人開始接觸編程是從js開始的,當時網上很多人說閉包是難點,各種地方對閉包的解釋也是千奇百怪。如今開始接觸js以外的各種編程語言,發現不光是js,php、...
摘要:如何在初學就理解閉包你需要接著讀下去。這樣定義閉包是函數和聲明該函數的詞法環境的組合。小結閉包在中隨處可見。閉包是中的精華部分,理解它需要具備一定的作用域執行棧的知識。 這是本系列的第 4 篇文章。 作為 JS 初學者,第一次接觸閉包的概念是因為寫出了類似下面的代碼: for (var i = 0; i < helpText.length; i++) { var item = he...
摘要:閉包引起的內存泄漏總結從理論的角度將由于作用域鏈的特性中所有函數都是閉包但是從應用的角度來說只有當函數以返回值返回或者當函數以參數形式使用或者當函數中自由變量在函數外被引用時才能成為明確意義上的閉包。 文章同步到github js的閉包概念幾乎是任何面試官都會問的問題,最近把閉包這塊的概念梳理了一下,記錄成以下文章。 什么是閉包 我先列出一些官方及經典書籍等書中給出的概念,這些概念雖然...
摘要:變量的作用域無非就是兩種全局變量和局部變量。其中內部函數中可以訪問外部函數的變量,是因為內部函數的作用域鏈中包含了外部函數的作用域也可以理解為內部函數的作用范圍輻射到了外部函數的作用范圍另一方面,在函數外部自然無法讀取函數內的局部變量。 以前學習的時候,了解過變量提升和閉包,但是沒有深入了解,網上查了資料,這里記錄下,只供參考。部分內容引用: https://www.cnblogs.c...
閱讀 2781·2023-04-25 14:41
閱讀 2375·2021-11-23 09:51
閱讀 3674·2021-11-17 17:08
閱讀 1667·2021-10-18 13:31
閱讀 5528·2021-09-22 15:27
閱讀 910·2019-08-30 15:54
閱讀 2222·2019-08-30 13:16
閱讀 728·2019-08-29 17:04