輕鬆理解JavaScript閉包

來源:互聯網
上載者:User

標籤:length   例子   com   對象   機制   ams   cti   for迴圈   數字   

摘要

閉包機制是JavaScript的重點和痛點,本文希望能協助大家輕鬆的學習閉包

一、什麼是閉包?

閉包就是可以訪問另一個函數範圍中變數的函數
下面列舉出常見的閉包實現方式,以例子講解閉包概念

function f1(){    var n=999;    nAdd=function(){n+=1}    function f2(){      alert(n);    }    return f2;  }  var result=f1();  result(); // 999  nAdd();  result(); // 1000

f1是f2的父函數,而f2被賦給了一個全域變數(return的值),這導致f2始終在記憶體中,而f2的存在依賴於f1,因此f1也始終在記憶體中,不會在調用結束後,被記憶體回收機制(garbage collection)回收,這便形成了閉包。
因此,可以這麼理解。閉包機制就是,如果A函數引用了另一個函數B的變數,但是B返回後A仍沒有返回,仍存在,因為A的引用,所以B的所有局部變數並不會隨B退出而登出,會一直存在,直到A登出。此時A就是閉包。

二、閉包的this指標

閉包通常在全域環境調用的,所以this通常指向window,具體情況還是需要視執行環境而言,總之this指向執行環境。
若需要閉包的this指向閉包的包含對象,則需要將包含對象的this作為變數傳進閉包。

三、使用閉包的注意點
  1. 由於閉包會使得函數中的變數都被儲存在記憶體中,記憶體消耗很大,所以不能濫用閉包,否則會造成網頁的效能問題,在IE中可能導致記憶體泄露。解決方案是,在退出函數之前,將不使用的局部變數全部刪除。

  2. 閉包會在父函數外部,改變父函數內部變數的值。所以,如果你把父函數當作對象(object)使用,把閉包當作它的公用方法(Public Method),把內部變數當作它的私人屬性(private value),這時一定要小心,不要隨便改變父函數內部變數的值。

四、解決一道閉包常見面試題

問題:

function onMyLoad(){            /*            拋出問題:                此題的目的是想每次點擊對應目標時彈出對應的數字下標 0~4,但實際是無論點擊哪個目標都會彈出數字5            問題所在:                arr 中的每一項的 onclick 均為一個函數執行個體(Function 對象),這個函數執行個體也產生了一個閉包域,                這個閉包域引用了外部閉包域的變數,其 function scope 的 closure 對象有個名為 i 的引用,                外部閉包域的私人變數內容發生變化,內部閉包域得到的值自然會發生改變            */            var arr = document.getElementsByTagName("p");            for(var i = 0; i < arr.length;i++){                arr[i].onclick = function(){                    alert(i);                }            }        }

解決方案
1、在外面再加一層函數,將i作為函數參數傳進來,這樣每次儲存的是函數內部的變數,與外部i不是同一個記憶體空間,而每次調用函數都會產生一個局部變數,所以可以保證每次儲存的值互不影響。

for(var i = 0; i<arr.length;i++){    arr[i].onclick = (function(arg){        return function () {            alert(arg);        }    })(i);}

2、用ES6新特let,將for迴圈的var i改成let i,這樣當前的i只在本輪迴圈有效,所以每一次迴圈的i其實都是一個新的變數。你可能會問,如果每一輪迴圈的變數i都是重新聲明的,那它怎麼知道上一輪迴圈的值,從而計算出本輪迴圈的值?這是因為 JavaScript 引擎內部會記住上一輪迴圈的值,初始化本輪的變數i時,就在上一輪迴圈的基礎上進行計算。

輕鬆理解JavaScript閉包

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.