摘要:當(dāng)閉包函數(shù)外部包含了一個匿名函數(shù)指向全局匿名函數(shù)執(zhí)行具有全局性指向原理每個函數(shù)在被調(diào)用時都會自動取得兩個特殊變量和。過度使用閉包可能會導(dǎo)致內(nèi)存占用過多閉包只能取得包含函數(shù)中任何變量的最后一個值所以要注意寫法
面試的時候一直會被問到什么是閉包,以前也不是很在意,更沒有去總結(jié)和歸納.
閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。
所以,在本質(zhì)上,閉包就是將函數(shù)內(nèi)部和函數(shù)外部連接起來的一座橋梁。
(一)閉包最基本的應(yīng)用:
少廢話,上代碼 還是<>的栗子,
function createComparisonFunction(propertyName) { return function(object1, object2) { var value1 = object1[propertyName]; var value2 = object2[propertyName]; if(value1 < value2) { return -1; } else if(value1 > value2) { return 1; } else { return 0; } }; } var compare = createComparisonFunction("name"); var result = compare({ name: "Nicholas" }, { name: "Greg" });
分析:
(1)閉包函數(shù)可以訪問其外部函數(shù)
return出來的這個匿名函數(shù)就是一個閉包函數(shù),這個匿名函數(shù)中的訪問了外部函數(shù)的活動對象,就是這個propertyName參數(shù)。因為外部的作用域鏈被這個匿名函數(shù)所包含(也可以理解為:compare函數(shù)包含
createComparisonFunction()函數(shù)的活動對象和全局變量對象),所以返回的這個匿名函數(shù)可以一直訪問他外部的這個propertyName以及全局變量。
(2)閉包所引用的外部變量不會因為所在作用域銷毀而銷毀
因為在返回的閉包函數(shù)中,引用了外部函數(shù)的活動對象,所以createComparisonFunction()內(nèi)的活動對象(即propertyName)在createComparisonFunction()執(zhí)行完后不會被銷毀。因為雖然createComparisonFunction執(zhí)行完后,會把其執(zhí)行環(huán)境中的作用域鏈銷毀,但是他的活動對象仍然被閉包函數(shù)引用,放入了匿名函數(shù)的執(zhí)行環(huán)境的作用域中
(二)閉包的副作用
(1).閉包只能取得包含函數(shù)中任何變量的最后一個值
function createFunctions(){ var result = new Array(); for (var i=0; i < 10; i++){ result[i] = function(){ return i; }; } return result; } var res = createFunctions(); console.log(res[0]()); //10 console.log(res[1]()); //10
原理:
因為每個函數(shù)的作用域鏈中都保存著 createFunctions() 函數(shù)的活動對象,所以它們引用的都是同一個變量 i 。 當(dāng)createFunctions()函數(shù)返回后,變量 i 的值是 10,此時每個函數(shù)都引用著保存變量 i 的同一個變量對象,所以在每個函數(shù)內(nèi)部 i 的值都是 10
解決方法:
獲取內(nèi)部函數(shù)的對象result[i]時,使用匿名函數(shù),并在匿名函數(shù)中再使用閉包函數(shù),使得當(dāng)前環(huán)境下的num被閉包函數(shù)函數(shù)調(diào)用,存儲在作用域中不會被釋放.
function createFunctions2(){ var result = new Array(); for(var i = 0 ; i <10 ; i++){ result[i] = (function(num){ return function(){ return num } })(i) } return result; } var res2 = createFunctions2(); console.log(res2[0]()); // 0 console.log(res2[1]()); // 1
原理:
定義了一個匿名函數(shù),并將立即執(zhí)行該匿名函數(shù)的結(jié)果賦給數(shù)組。這里的匿名函數(shù)有一個參數(shù) num,也就是最終的函數(shù)要返回的值。在調(diào)用每個匿名函數(shù)時,我們傳入了變量 i。由于函數(shù)參數(shù)是按值傳遞的,所以就會將變量 i 的當(dāng)前值復(fù)制給參數(shù) num。而在這個匿名函數(shù)內(nèi)部,又創(chuàng)建并返回了一個訪問 num 的閉包。這樣一來,result 數(shù)組中的每個函數(shù)都有自己num 變量的一個副本,因此就可以返回各自不同的數(shù)值了。
(2).當(dāng)閉包函數(shù)外部包含了一個匿名函數(shù),this指向全局
var name = "The Window"; var object = { name: "My Object", getNameFunc: function () { return function () { //匿名函數(shù)執(zhí)行具有全局性 return this.name; //this指向window }; } }; console.log(object.getNameFunc()()) // The Window
原理:
每個函數(shù)在被調(diào)用時都會自動取得兩個特殊變量:this 和 arguments。內(nèi)部函
數(shù)在搜索這兩個變量時,只會搜索到其活動對象為止,所以無法獲取到外部的this,此時getNameFunc()返回的是一個匿名函數(shù),并且匿名函數(shù)具有全局性,因此this指向全局的window
解決方案:
把外部作用域中的 this 對象保存在一個閉包能夠訪問到的變量里,就可以讓閉包訪問該對象了
var name2 = "The Window"; var object2 = { name:"My Object", getNameFunc:function(){ var that = this; //將外部函數(shù)的this保存在外部函數(shù)的活動對象中(函數(shù)中申明的變量中) return function (){ return that.name } } } console.log(object2.getNameFunc()()) //My Object
(三)
閉包的缺點
(1).由于閉包會攜帶包含它的函數(shù)的作用域,因此會比其他函數(shù)占用更多的內(nèi)存。過度使用閉包可能會導(dǎo)致內(nèi)存占用過多
(2).閉包只能取得包含函數(shù)中任何變量的最后一個值,所以要注意寫法
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/98603.html
摘要:完美的閉包,對,閉包就這么簡單。這僅僅是閉包的一部分,閉包利用函數(shù)作用域達到了訪問外層變量的目的。此時一個完整的閉包實現(xiàn)了,的垃圾回收機制由于閉包的存在無法銷毀變量。 1.閉包是指有權(quán)訪問另一個函數(shù)作用域中的變量的函數(shù)。 上面這段話來自 javascript 高級程序設(shè)計 第三版 P178 。作者說閉包是一個函數(shù),它有訪問另一個函數(shù)作用域中的變量的能力。 2.函數(shù)訪問它被創(chuàng)建時所處的...
摘要:內(nèi)部的稱為內(nèi)部函數(shù)或閉包函數(shù)。過度使用閉包會導(dǎo)致性能下降。,閉包函數(shù)分為定義時,和運行時。循環(huán)會先運行完畢,此時,閉包函數(shù)并沒有運行。閉包只能取得外部函數(shù)中的最后一個值。事件綁定種的匿名函數(shù)也是閉包函數(shù)。而對象中的閉包函數(shù),指向。 閉包概念解釋: 閉包(也叫詞法閉包或者函數(shù)閉包)。 在一個函數(shù)parent內(nèi)聲明另一個函數(shù)child,形成了嵌套。函數(shù)child使用了函數(shù)parent的參數(shù)...
摘要:大名鼎鼎的閉包面試必問。閉包的作用是什么??吹介]包在哪了嗎閉包到底是什么五年前,我也被這個問題困擾,于是去搜了并總結(jié)下來。關(guān)于閉包的謠言閉包會造成內(nèi)存泄露錯。閉包里面的變量明明就是我們需要的變量,憑什么說是內(nèi)存泄露這個謠言是如何來的因為。 本文為饑人谷講師方方原創(chuàng)文章,首發(fā)于 前端學(xué)習(xí)指南。 大名鼎鼎的閉包!面試必問。請用自己的話簡述 什么是「閉包」。 「閉包」的作用是什么。 首先...
摘要:到底什么是閉包這個問題在面試是時候經(jīng)常都會被問,很多小白一聽就懵逼了,不知道如何回答好。上面這么說閉包是一種特殊的對象。閉包的注意事項通常,函數(shù)的作用域及其所有變量都會在函數(shù)執(zhí)行結(jié)束后被銷毀。從而使用閉包模塊化代碼,減少全局變量的污染。 閉包,有人說它是一種設(shè)計理念,有人說所有的函數(shù)都是閉包。到底什么是閉包?這個問題在面試是時候經(jīng)常都會被問,很多小白一聽就懵逼了,不知道如何回答好。這個...
摘要:也許最好的理解是閉包總是在進入某個函數(shù)的時候被創(chuàng)建,而局部變量是被加入到這個閉包中。在函數(shù)內(nèi)部的函數(shù)的內(nèi)部聲明函數(shù)是可以的可以獲得不止一個層級的閉包。 前言 總括 :這篇文章使用有效的javascript代碼向程序員們解釋了閉包,大牛和功能型程序員請自行忽略。 譯者 :文章寫在2006年,可直到翻譯的21小時之前作者還在完善這篇文章,在Stackoverflow的How do Java...
閱讀 2369·2021-11-16 11:52
閱讀 2341·2021-11-11 16:55
閱讀 767·2021-09-02 15:41
閱讀 3000·2019-08-30 15:54
閱讀 3160·2019-08-30 15:54
閱讀 2266·2019-08-29 15:39
閱讀 1523·2019-08-29 15:18
閱讀 985·2019-08-29 13:00