什么是閉包
《JavaScript高級(jí)程序設(shè)計(jì)》這樣描述:
最常見(jiàn)的閉包結(jié)構(gòu)如下
function aaa(){
var name = "xxx"
return function bbb(){
alert(name);
}
}
如上代碼切蟋,bbb函數(shù)
內(nèi)可以訪問(wèn)aaa函數(shù)
作用域內(nèi)的變量
閉包的特性
看一下這一段的封裝偷俭,jQuery
也采用了類似的封裝方式抄淑,外部的方法和變量就不會(huì)污染閉包內(nèi)部的東西衩婚,同時(shí)剔应,閉包內(nèi)的變量也會(huì)有效的保存下來(lái)
function person(name) {
// 變量作用域?yàn)楹瘮?shù)內(nèi)部咒林,外部無(wú)法訪問(wèn)熬拒,防止了變量名沖突和污染
var name = '小明';
this.sayName= function() {
alert(name)
}
this.changeName= function(newName) {
name = newName
}
}
// 外部無(wú)法訪問(wèn)內(nèi)部變量
let a = new person()
console.log(a.name) // undefiend
a.changeName('小白')
// 這里修改的name會(huì)保存下來(lái)
a.sayName() // 小白
常見(jiàn)的定時(shí)器問(wèn)題
for( var i = 0; i < 5; i++ ) {
setTimeout(() => {
console.log( i );
}, 1000)
}
得到結(jié)果 5個(gè)5
setTimeout函數(shù)在當(dāng)前執(zhí)行隊(duì)列的最后執(zhí)行,獲取到的i
是最外部作用域的i=5
,所以得到5個(gè)5
那么如果想1s后得到0-4怎么做垫竞?在for循環(huán)內(nèi)創(chuàng)建閉包
for (var i = 0; i < 5; i++) {
(function(j) {
setTimeout(function() {
console.log(j);
},1000)
})(i)
}
同樣setTimeout在執(zhí)行隊(duì)列的最后執(zhí)行澎粟,獲取到的j
是外部函數(shù)的j
,由于閉包中的變量會(huì)保存下來(lái),每一次獲取的j
分別是0,1,2,3,4
注意事項(xiàng)
由于閉包會(huì)常駐內(nèi)存欢瞪,使用不當(dāng)會(huì)導(dǎo)致內(nèi)存溢出活烙。
測(cè)試題
function fun(n, o) {
console.log(o);
return {
fun: function(m) {
return fun(m, n);
}
};
}
var a = fun(0); // ?
a.fun(1); // ?
a.fun(2); // ?
a.fun(3); // ?
var b = fun(0).fun(1).fun(2).fun(3); // ?
var c = fun(0).fun(1); // ?
c.fun(2); // ?
c.fun(3); // ?