JavaScript高級__深入瞭解閉包

理解閉包

1.如何產生閉包

當一個嵌套的內部(子)函數引用了嵌套的外部(父)函數的變量(函數)時,就產生了閉包

2.閉包到底是什麼

閉包是嵌套的內部函數

包含被引用變量(函數)的對象

注意:閉包存在於嵌套的內部函數中

3.產生閉包的條件

函數嵌套

內部函數引用了外部函數的數據(變量/函數)

function fn1() {
  // 此時閉包就已經產生了(函數提升,內部函數對象已經創建了)
  var a =2
  function fn2() {
    a++
    console.log(a)
  }
  return fn2
}
var f = fn1()
f() // 3
f() // 4
f = null // 閉包死亡(包含閉包的函數對象成爲垃圾對象)

常見的閉包

1.將函數作爲另一個函數的返回值

2.將函數作爲實參傳遞給另一個函數調用

閉包的作用

1.延長局部變量的生命週期

2.從外部可以(間接)操作函數內部的局部變量

閉包的生命週期

1.產生:在嵌套內部函數定義執行完成就產生了(不是在調用時)

2.死亡:在嵌套內部函數成爲垃圾對象時

閉包的應用

自定義JS模塊

*具有特定功能得js文件

*將所有的數據和功能都封裝在一個函數內部(私有的)

*只向外暴露一個包含n個方法的對象或函數

*模塊的使用者,只需要通過模塊暴露的對象調用方法來實現對應的功能

案例一

function myModule() {
  // 私有變量
  var msg = 'Hello World'
  // 操作私有變量的函數
  function upperCase() {
    console.log('upperCase()' + msg.toUpperCase())
  }
  function lowerCase() {
    console.log('lowerCase()' + msg.toLowerCase())
  }
  // 向外部暴露對象(給外部使用的方法)
  return {
    upperCase: upperCase,
    lowerCase: lowerCase
  }
}

案例二

(function () {
  // 私有變量
  var msg = 'Hello World'
  // 操作私有變量的函數
  function upperCase() {
    console.log('upperCase()' + msg.toUpperCase())
  }
  function lowerCase() {
    console.log('lowerCase()' + msg.toLowerCase())
  }
  // 直接掛在window上
  window.myModule = {
    upperCase: upperCase,
    lowerCase: lowerCase
  }
})()

閉包的缺點以及解決

1.缺點

  *函數執行完後,函數內的局部變量沒有釋放,佔用內存時間變長

  *容易造成內存泄漏

2.解決

  *能不用閉包就不用

  *及時釋放 (賦值null)

閉包代碼案例

代碼一

var name = "window"
var obj = {
  name : 'object',
  getName : function() {
    return function() {
      return this.name;
    }
  }
}
console.log(obj.getName()()) // window

代碼二

var name = "window"
var obj = {
  name : 'object',
  getName : function() {
    var that = this
    return function() {
      return that.name
    }
  }
}
console.log(obj.getName()()) // object

代碼三

function fun(n, o) {
  console.log(o)
  return {
    fun: function(m) {
      return fun(m, n)
    }
  }
}
var aa = fun(0); // undefined
aa.fun(1); // 0
aa.fun(2); // 0
aa.fun(3); // 0

var bb = fun(0).fun(1).fun(2).fun(3); // undefined 0 1 2

var cc = fun(0).fun(1); // undefined 0
cc.fun(2); // 1
cc.fun(3); // 1

內存溢出與內存泄漏

1.內存溢出

  *一種程序運行出現的錯誤

  *當程序運行需要的內存超過了剩餘的內存時,就拋出內存溢出的錯誤

2.內存泄漏

  *佔用的內存沒有及時釋放

  *內存泄漏積累多了就容易導致內存溢出

  *常見的內存泄漏

    i意外的全局變量

    ii沒有及時清理的計時器或回調函數

    iii閉包

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章