日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

闭包

發(fā)布時(shí)間:2025/6/15 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 闭包 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.閉包
2.原型鏈
3.深/淺拷貝
4.this指向
5.柯里式
6.ES6
7.webpack 配置 打包
8.虛擬dom
9.js 堆棧

1.浮動(dòng)原理 為什么要清浮動(dòng)
2.css選擇器優(yōu)先級(jí) 瀏覽器怎么進(jìn)行解讀及渲染
3.absolute relative的定位相對(duì)圓點(diǎn)是什么?

1.閉包

我個(gè)人認(rèn)為,理解閉包的關(guān)鍵在于:外部函數(shù)調(diào)用之后其變量對(duì)象本應(yīng)該被銷毀,但閉包的存在使我們?nèi)匀豢梢栽L問(wèn)外部函數(shù)的變量對(duì)象,這就是閉包的重要概念。

//看一個(gè)閉包的例子 function outer () {var a = 1;//定義一個(gè)內(nèi)部變量return function() {return a;//返回a的變量值}; } var b = outer(); console.log(b());//打印1

創(chuàng)建閉包最常見(jiàn)方式,就是在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)。
閉包的作用域包含著它自己的作用域,以及包含它的函數(shù)的作用域和全局作用域。

閉包的注意事項(xiàng):
通常,函數(shù)的作用域及其所有變量都會(huì)在函數(shù)執(zhí)行結(jié)束后被銷毀。但是,在創(chuàng)建一個(gè)閉包后,這個(gè)函數(shù)的作用域就會(huì)一直保存到閉包不存在為止。

function makeAdder(x) {return function(y) {return x + y;}; } var add5 = makeAdder(5); var add10 = makeAdder(10);console.log(add5(2));//7 console.log(add10(2));//12//釋放對(duì)閉包的引用 add5 = null; add10 = null;

從上述代碼可以看到add5和add10都是閉包。它們共同享有相同的函數(shù)定義,但是保存了不同的環(huán)境。在add5的環(huán)境中,x為5。而在 add10 中,x 則為 10。最后通過(guò) null 釋放了 add5 和 add10 對(duì)閉包的引用。
在javascript中,如果一個(gè)對(duì)象不再被引用,那么這個(gè)對(duì)象就會(huì)被垃圾回收機(jī)制回收;
如果兩個(gè)對(duì)象互相引用,而不再被第3者所引用,那么這兩個(gè)互相引用的對(duì)象也會(huì)被回收。
閉包只能取得包含函數(shù)中任何變量的最后一個(gè)值

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

大家看一下上面這個(gè)代碼,arr數(shù)組中包含了10個(gè)匿名函數(shù),每個(gè)匿名函數(shù)都能訪問(wèn)外部函數(shù)的變量i,那么i是多少呢?
當(dāng)arrFunc執(zhí)行完畢后,其作用域被銷毀,但它的變量對(duì)象仍保存在內(nèi)存中,得以被匿名訪問(wèn),這時(shí)i的值為10。
要想保存在循環(huán)過(guò)程中每一個(gè)i的值,需要在匿名函數(shù)外部再套用一個(gè)匿名函數(shù),在這個(gè)匿名函數(shù)中定義另一個(gè)變量并且立即執(zhí)行來(lái)保存i的值。

function arrFunc() {var arr = [];for(var i=0;i<10;i++) {arr[i] = function(num) {return function() {return num;};}(i);}return arr; } console.log( arrFunc()[1]() );

這時(shí)最內(nèi)部的匿名函數(shù)訪問(wèn)的是num的值,所以數(shù)組中10個(gè)匿名函數(shù)的返回值就是1-10。
閉包中的this對(duì)象

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

在上面這段代碼中,obj.getName()()實(shí)際上是在全局作用域中調(diào)用了匿名函數(shù),this指向了window。
這里要理解函數(shù)名與函數(shù)功能是分割開(kāi)的,不要認(rèn)為函數(shù)在哪里,其內(nèi)部的this就指向哪里。
window才是匿名函數(shù)功能執(zhí)行的環(huán)境。
如果想使this指向外部函數(shù)的執(zhí)行環(huán)境,可以這樣改寫(xiě):

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

內(nèi)存泄露
閉包會(huì)引用包含函數(shù)的整個(gè)變量對(duì)象,如果閉包的作用域鏈中保存著一個(gè)HTML元素,那么就意味著該元素?zé)o法被銷毀。所以我們有必要在對(duì)這個(gè)元素操作完之后主動(dòng)銷毀。

function assignHandler() {var ele = document.getElementById('demo');var id = ele.id;ele.onclick = function() {alert(id);};ele = null; }

函數(shù)內(nèi)部的定時(shí)器
當(dāng)函數(shù)內(nèi)部的定時(shí)器引用了外部函數(shù)的變量對(duì)象時(shí),該變量對(duì)象不會(huì)被銷毀。

(function() {var a = 0;setInterval(function(){console.log(a++);},1000); })()

閉包的應(yīng)用
應(yīng)用閉包的主要場(chǎng)合是:設(shè)計(jì)私有的方法和變量。
任何在函數(shù)中定義的變量,都可以認(rèn)為是私有變量,因?yàn)椴荒茉诤瘮?shù)外部訪問(wèn)這些變量。私有變量包括函數(shù)的參數(shù)、局部變量和函數(shù)內(nèi)定義的其他函數(shù)。
把有權(quán)訪問(wèn)私有變量的公有方法稱為特權(quán)方法(privileged method)。

function Animal() {//私有變量var series = "哺乳動(dòng)物";function run() {console.log("Run!!!");}//特權(quán)方法this.getSeries = function() {return series;} }

在這里,我們需要理解兩個(gè)概念:
模塊模式(The Module Pattern):為單例創(chuàng)建私有變量和方法。
單例(singleton):指的是只有一個(gè)實(shí)例的對(duì)象。JavaScript 一般以對(duì)象字面量的方式來(lái)創(chuàng)建一個(gè)單例對(duì)象。
運(yùn)用閉包的關(guān)鍵
閉包引用外部函數(shù)變量對(duì)象中的值;
在外部函數(shù)的外部調(diào)用閉包。
閉包的缺陷
閉包的缺點(diǎn)就是常駐內(nèi)存會(huì)增大內(nèi)存使用量,并且使用不當(dāng)很容易造成內(nèi)存泄露。
如果不是因?yàn)槟承┨厥馊蝿?wù)而需要閉包,在沒(méi)有必要的情況下,在其它函數(shù)中創(chuàng)建函數(shù)是不明智的,因?yàn)殚]包對(duì)腳本性能具有負(fù)面影響,包括處理速度和內(nèi)存消耗。
最后 來(lái)一道有關(guān)閉包的面試題
下面代碼中,標(biāo)記 ? 的地方輸出分別是什么?

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

為什么要用閉包

總結(jié)

以上是生活随笔為你收集整理的闭包的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。