1. 程式人生 > 程式設計 >讓我們一起來學習一下什麼是javascript的閉包

讓我們一起來學習一下什麼是javascript的閉包

目錄
  • 一、常見的閉包
  • 二、例項詳解
  • 總結
什麼是閉包:
閉包是一個存在內部函式的引用關係。
該引用指向的是外部函式的區域性變數物件(前提是內部函式使用了外部函式的區域性變數)
閉包的作用:
延長外部函式變數物件的生命週期
使用閉包能夠間接的從函式外部訪問函式內部的私有變數

一、常見的閉包

functiowww.cppcns.comn outer() {
  var a = 1
  function inner() {
    console.log(a)    //1
  }
  inner()
}
outer()

二、例項詳解

function createFunc() {
  var result = new Array()
  for (var i = 0; i < 10; i++) {
    result[i] = functihttp://www.cppcns.com
on () { console.log(i) } } return result } var result = createFunc() result[0]() //10 result[1]() //10 result[2]() //10 result[3]() //10 result[4]() //10 result[5]() //10 result[6]() //10 result[7]() //10

首先在程式碼執行前,會先建立一個全域性的物件,其中包含著全域性的屬性,並且將其放入全域性上下文作用域鏈頂端,並且也將其放入每一個函式的作用域鏈頂端。以這個例子為例。如圖所示

在這裡插入圖片描述

在初始化結束後,開始執行程式碼,此時就會建立一個新的物件,叫做Active Object,其中放入一些引數,並且將其壓入createFunc函式的作用域鏈中。

在這裡插入圖片描述

因為在createFunc中仍然定義函式result[i]..,所以在執行程式碼前,該函式會形成作用域鏈。

在這裡插入圖片描述

此時開始執行createFunc函式,當指向完畢後,createFunc中的作用域連結串列現為。如下圖所示。此時result為一個數組。並且Active object已經從createFunc作用域鏈的頂部刪除。

在這裡插入圖片描述

此時開始執行result[0](這裡以result[0]為例,其他的一樣),此時執行result[0]之前,應該建立一個新的Active object物件,將其放入result[0]執行作用域棧中。如圖所示

在這裡插入圖片描述

此時函式執行中需要訪問i,但是在ahttp://www.cppcns.com

ctive object並不存在i,所以此時需要沿著作用域鏈進行查詢,在createFunc中找到i,並且i的值為10,所以最終列印的值都是10。在createFunc執行完畢後,其建立的物件並沒有被垃圾回收掉,因為在result[0]中的i依然保持對該物件的引用。

這個例子的解決方法如下所示,就是設定一個立即執行函式,每一個下標對應的函式,都是立即執行函式,當立即執行函式執行時,每一個函式的上下文物件中都會存在為正確的下標值。

function createFunc() {
  var result = new Array()
  for (var i = 0; i < 10; i++) {
    result[i] = (function (num) {
      return function() {
        console.log(num)
      }
    })(i)
  }
  return result
}
var result = createFunc()
result[0]() //0
result[1]() //1
result[2]() //2
result[3]() //3
result[4]() /www.cppcns.com/4
result[5]() //5
resulwww.cppcns.comt[6]() //6
result[7]() //7

總結

本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注我們的更多內容!