這篇文章帶給大家的內容是關於javascript閉包函數的基本使用以及會遇到的問題解決,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。
面試的時候一直會被問到什麼是閉包,以前也不是很在意,更沒有去總結和歸納.
閉包就是能夠讀取其他函數內部變數的函數。
所以,在本質上,閉包就是將函數內部和函數外部連接起來的一座橋樑。
(一)閉包最基本的應用:
少废话,上代码 还是>的栗子,
function createComparisonFunction(propertyName) { return function(object1, object2) { var value1 = object1[propertyName]; var value2 = object2[propertyName]; if(value1 value2) { return 1; } else { return 0; } }; } var compare = createComparisonFunction("name"); var result = compare({ name: "Nicholas" }, { name: "Greg" });
分析:
(1)閉包函數可以存取其外部函數
return出來的這個匿名函數就是一個閉包函數,這個匿名函數中的存取了外部函數的活動物件,就是這個propertyName參數。因為外部的作用域鏈被這個匿名函數所包含(也可以理解為:compare函數包含
createComparisonFunction()函數的活動對象和全局變量對象),所以返回的這個匿名函數可以一直訪問他外部的這個propertyName以及全域變數。
(2)閉包所引用的外部變數不會因為所在作用域銷毀而銷毀
因為在返回的閉包函數中,引用了外部函數的活動對象,所以createComparisonFunction()內的活動對象(即propertyName)在createComparisonFunction()執行完後不會被銷毀。因為雖然createComparisonFunction執行完後,會把其執行環境中的作用域鏈銷毀,但是他的活動對象仍然被閉包函數引用,放入了匿名函數的執行環境的作用域中
(二)閉包的副作用
(1).閉包只能取得包含函數中任何變數的最後一個值
function createFunctions(){ var result = new Array(); for (var i=0; i <p>原理:<br>因為每個函數的作用域鏈中都保存著createFunctions() 函數的活動對象,所以它們所引用的都是同一個變數i 。當createFunctions()函數傳回後,變數i 的值是10,此時每個函數都引用著保存變數i 的同一個變數對象,所以在每個函數內部i 的值都是10</p><p>解決方法:</p><pre class="brush:php;toolbar:false">获取内部函数的对象result[i]时,使用匿名函数,并在匿名函数中再使用闭包函数,使得当前环境下的num被闭包函数函数调用,存储在作用域中不会被释放.
function createFunctions2(){ var result = new Array(); for(var i = 0 ; i <p>原理:<br>定義了一個匿名函數,並將立即執行該匿名函數的結果賦給陣列。這裡的匿名函數有一個參數 num,也就是最終的函數要傳回的值。在呼叫每個匿名函數時,我們傳入了變數 i。由於函數參數是按值傳遞的,所以就會將變數 i 的目前值複製給參數 num。而在這個匿名函數內部,又建立並回傳了一個訪問 num 的閉包。這樣一來,result 陣列中的每個函數都有自己num 變數的副本,因此就可以傳回各自不同的數值了。 </p><p>(2).當閉包函數外部包含了一個匿名函數,this指向全域</p><pre class="brush:php;toolbar:false"> var name = "The Window"; var object = { name: "My Object", getNameFunc: function () { return function () { //匿名函数执行具有全局性 return this.name; //this指向window }; } }; console.log(object.getNameFunc()()) // The Window
原理:
每個函數在被呼叫時都會自動取得兩個特殊變量:this 和arguments。內部函
數在搜尋這兩個變數時,只會搜尋到其活動物件為止,所以無法取得外部的this,此時getNameFunc()傳回的是一個匿名函數,且匿名函數具有全域性,因此this指向全域的window
解決方案:
把外部作用域中的this 物件保存在一個閉包能夠存取到的變數裡,就可以讓閉包存取該物件了
var name2 = "The Window"; var object2 = { name:"My Object", getNameFunc:function(){ var that = this; //将外部函数的this保存在外部函数的活动对象中(函数中申明的变量中) return function (){ return that.name } } } console.log(object2.getNameFunc()()) //My Object
(三)
閉包的缺點
(1).由於閉包會攜帶包含它的函數的作用域,因此會比其他函數佔用更多的記憶體。過度使用閉包可能會導致記憶體佔用過多
(2).閉包只能取得包含函數中任何變數的最後一個值,所以要注意寫法
唧唧陸地# 3#
##
7 中使用 · 作用內使用期間 12 分鐘時閱讀 12 分鐘
(一)閉包最基本的應用:
少废话,上代码 还是>的栗子,
function createComparisonFunction(propertyName) { return function(object1, object2) { var value1 = object1[propertyName]; var value2 = object2[propertyName]; if(value1 value2) { return 1; } else { return 0; } }; } var compare = createComparisonFunction("name"); var result = compare({ name: "Nicholas" }, { name: "Greg" });
分析:
(1)閉包函數可以存取其外部函數
return出來的這個匿名函數就是一個閉包函數,這個匿名函數中的存取了外部函數的活動物件,就是這個propertyName參數。因為外部的作用域鏈被這個匿名函數所包含(也可以理解為:compare函數包含
createComparisonFunction()函數的活動對象和全局變量對象),所以返回的這個匿名函數可以一直訪問他外部的這個propertyName以及全域變數。
(2)閉包所引用的外部變數不會因為所在作用域銷毀而銷毀
因為在返回的閉包函數中,引用了外部函數的活動對象,所以createComparisonFunction()內的活動對象(即propertyName)在createComparisonFunction()執行完後不會被銷毀。因為雖然createComparisonFunction執行完後,會把其執行環境中的作用域鏈銷毀,但是他的活動對象仍然被閉包函數引用,放入了匿名函數的執行環境的作用域中
#(二)閉包的副作用
(1).閉包只能取得包含函數中任何變數的最後一個值
function createFunctions(){ var result = new Array(); for (var i=0; i <p>原理:<br>因為每個函數的作用域鏈中都保存著createFunctions() 函數的活動對象,所以它們所引用的都是同一個變數i 。當createFunctions()函數傳回後,變數i 的值是10,此時每個函數都引用著保存變數i 的同一個變數對象,所以在每個函數內部i 的值都是10</p><p>解決方法:</p><pre class="brush:php;toolbar:false">获取内部函数的对象result[i]时,使用匿名函数,并在匿名函数中再使用闭包函数,使得当前环境下的num被闭包函数函数调用,存储在作用域中不会被释放.
function createFunctions2(){ var result = new Array(); for(var i = 0 ; i <p>原理:<br>定義了一個匿名函數,並將立即執行該匿名函數的結果賦給陣列。這裡的匿名函數有一個參數 num,也就是最終的函數要傳回的值。在呼叫每個匿名函數時,我們傳入了變數 i。由於函數參數是按值傳遞的,所以就會將變數 i 的目前值複製給參數 num。而在這個匿名函數內部,又建立並回傳了一個訪問 num 的閉包。這樣一來,result 陣列中的每個函數都有自己num 變數的副本,因此就可以傳回各自不同的數值了。 </p><p>(2).當閉包函數外部包含了一個匿名函數,this指向全域</p><pre class="brush:php;toolbar:false"> var name = "The Window"; var object = { name: "My Object", getNameFunc: function () { return function () { //匿名函数执行具有全局性 return this.name; //this指向window }; } }; console.log(object.getNameFunc()()) // The Window
原理:
每個函數在被呼叫時都會自動取得兩個特殊變量:this 和arguments。內部函
數在搜尋這兩個變數時,只會搜尋到其活動物件為止,所以無法取得外部的this,此時getNameFunc()傳回的是一個匿名函數,且匿名函數具有全域性,因此this指向全域的window
解決方案:
把外部作用域中的this 物件保存在一個閉包能夠存取到的變數裡,就可以讓閉包存取該物件了
var name2 = "The Window"; var object2 = { name:"My Object", getNameFunc:function(){ var that = this; //将外部函数的this保存在外部函数的活动对象中(函数中申明的变量中) return function (){ return that.name } } } console.log(object2.getNameFunc()()) //My Object
(三)
閉包的缺點
(1).由於閉包會攜帶包含它的函數的作用域,因此會比其他函數佔用更多的記憶體。過度使用閉包可能會導致記憶體佔用過多
(2).閉包只能取得包含函數中任何變數的最後一個值,所以要注意寫法
#評論
時間排序
以上是javascript閉包函數的基本使用以及會遇到的問題解決的詳細內容。更多資訊請關注PHP中文網其他相關文章!