閉包

閉包:一個函數被其外部函數以外的變量調用時,就形成了閉包。

function outer(){
    function inner(){
        console.log("hello baby~")
    }
    return inner
}
var f = outer()
f()

申明變量f,將outer()賦值給變量。這就是一個簡單的閉包!

for打印出0 - 9

閉包只能取得包含函數中任何變量的最後一個值,這是因爲閉包所保存的是整個變量對象,而不是某個特殊的變量

function test () {
  var array = []
  for (var i = 0; i < 10; i++) {
    array[i] = function () {
      return i
    }
  }

  for (var a = 0; a < 10; a++) {
    console.log(array[a]())
  }
}
test() // 打印出 連續10個10

上例中調用了test(),執行完for (var i = 0; i < 10; i++)時i=10。再接下去執行for (var a = 0; a < 10; a++),調用array[]()向上尋找i,找到了同一作用域的i爲10,同一作用域中同一變量名的變量值肯定是相同的。而我們希望的是打印出0 - 9,下例中我們通過修改 i 的作用域來實現

function test () {
  var array = []
  for (let i = 0; i < 10; i++) {
    array[i] = function () {
      return i
    }
  }

  for (var a = 0; a < 10; a++) {
    console.log(array[a]())
  }
}
test() // 打印出 0 - 9

for (let i = 0; i < 10; i++)在這裏每次循環的塊作用域都被劫持了,並且每次迭代i都被重新聲明。 即在此時,每層迭代會生成一個塊作用域,並且變量i的值被定義爲上次結算的值。另外一種方式

function test () {
  var array = []
  for (var i = 0; i < 10; i++) {
    array[i] = function (a) {
      return function(){
        return a
      }
    }(i)
  }

  for (var a = 0; a < 10; a++) {
    console.log(array[a]())
  }
}
test() // 打印出 0 - 9

 this 對象

var name = 'mm';
var obj = {
    name:'ww',
    getName:()=>{
        return ()=>{
            console.log(this.name)
        }
    }
    
}
obj.getName()(); //打印出 mm

obj.getName()()實際上是在全局作用域中調用了匿名函數,this指向了window。這裏要理解函數名與函數功能(或者稱函數值)是分割開的,不要認爲函數在哪裏,其內部的this就指向哪裏。匿名函數的執行環境具有全局性,因此其 this 對象通常指向 window。

var name = 'mm';
var obj ={
   name:'ww',
   getName:()=>{
     var that = this;
     return ()=>{
        console.log(that.name);
     }
   }
}
obj.getName()();//打印出 ww

閉包優缺點

優點:局部變量不被全局污染

缺點:過度使用閉包,會導致內存佔用過多。

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