您好,登錄后才能下訂單哦!
本文小編為大家詳細(xì)介紹“es6有沒(méi)有閉包”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“es6有沒(méi)有閉包”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。
es6有閉包。在es6中,在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù),把內(nèi)嵌的函數(shù)稱(chēng)為閉包,它可以訪問(wèn)外部函數(shù)的局部變量;簡(jiǎn)單來(lái)說(shuō),閉包指有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域中變量的函數(shù)。閉包的主要作用:延伸了變量的作用范圍。由于閉包會(huì)使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗很大,所以不能濫用閉包,否則會(huì)造成網(wǎng)頁(yè)的性能問(wèn)題,在IE中可能導(dǎo)致內(nèi)存泄露。
變量根據(jù)作用域的不同分為兩種:全局變量和局部變量。
函數(shù)內(nèi)部可以使用全局變量。
函數(shù)外部不可以使用局部變量。
當(dāng)函數(shù)執(zhí)行完畢,本作用域內(nèi)的局部變量會(huì)銷(xiāo)毀。
在es6中,閉包(closure)指有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域中變量的函數(shù)。簡(jiǎn)單理解:一個(gè)作用域可以訪問(wèn)另外一個(gè)函數(shù)內(nèi)部的局部變量。
閉包:在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù),把內(nèi)嵌的函數(shù)稱(chēng)為閉包,它可以訪問(wèn)外部函數(shù)的局部變量
// fun 這個(gè)函數(shù)作用域 訪問(wèn)了另外一個(gè)函數(shù) fn 里面的局部變量 num
function fn(){
let num = 10
function fun(){
console.log(num)
}
fun()
}
fn() //10
閉包的主要作用:延伸了變量的作用范圍。
// fn 外面的作用域可以訪問(wèn)fn 內(nèi)部的局部變量
function fn(){
let num = 10
// 方法一: 先定義再返回函數(shù)
function fun(){
console.log(num)
}
return fun //返回 fun函數(shù)
}
let f = fn()
f() //10
// fn 外面的作用域可以訪問(wèn)fn 內(nèi)部的局部變量
function fn(){
let num = 10
// 方法二: 直接返回函數(shù)
return function(){
console.log(num)
}
}
let f = fn()
f() //10
(1)用來(lái)返回值
//以閉包的形式將 name 返回
function fun(){
let name = 'woniu'
//定義閉包
return function f1(){
return name
}
}
let ft = fun() //因?yàn)閒un函數(shù)的返回值是f1函數(shù),ft實(shí)質(zhì)是一個(gè)函數(shù)
let na = ft() //調(diào)用ft函數(shù),實(shí)際調(diào)用的就是f1函數(shù)
console.log(na); //woniu
(2)函數(shù)賦值:在函數(shù)內(nèi)部定義函數(shù)表達(dá)式
var f2
function fn(){
let name = '曹操'
f2 = function(){ //閉包,將外部函數(shù)的name變量作為閉包的返回值
return name
}
}
fn() //必須先調(diào)用fn函數(shù),否則f2不是一個(gè)函數(shù)
console.log(f2()); //曹操
(3)把閉包作為函數(shù)的參數(shù)
function fn(){
let name = '蝸牛學(xué)苑'
//定義閉包
return function callback(){
return name
}
}
let f1 = fn() //將fn函數(shù)的返回值callback賦給f1
function f2(temp){
console.log(temp()) //輸出temp函數(shù)的返回值,實(shí)際調(diào)用了閉包c(diǎn)allback
}
//調(diào)用f2函數(shù):將f1作為實(shí)參傳遞給temp
f2(f1)
(4)立即執(zhí)行函數(shù)中使用閉包
//立即執(zhí)行函數(shù)
(function(){
let name = '蝸牛學(xué)苑'
let f1 = function(){
return name
}
fn2(f1) //調(diào)用fn2函數(shù),將閉包f1作為實(shí)參傳遞給fn2函數(shù)
})()
function fn2(temp){ //temp是一個(gè)形參,接收f(shuō)1
console.log(temp()); //對(duì)temp的調(diào)用,實(shí)際調(diào)用的是閉包f1
}
(5)循環(huán)賦值
(function(){
for (let i = 1; i <= 10; i++) {
(
function(j){
setTimeout(function(){
console.log(j);
},j*1000)
}
)(i)
}
})()
(6)將閉包封裝到對(duì)象中
function fun(){
let name = '蝸牛學(xué)苑'
setName = function(na){ //setName是閉包,用來(lái)設(shè)置外部函數(shù)的變量值
name = na
}
getName = function(){ //getName是閉包,用來(lái)返回外部函數(shù)的變量值
return name
}
//外部fun函數(shù)的返回值,將閉包封裝到對(duì)象中返回
return {
setUserName:setName,
getUserName:getName
}
}
let obj =fun() //將fun函數(shù)返回值(對(duì)象)賦給obj
console.log('用戶(hù)名:',obj.getUserName()) //蝸牛學(xué)苑
obj.setUserName('石油學(xué)苑')
console.log('用戶(hù)名:',obj.getUserName()) //石油學(xué)苑
(7)通過(guò)閉包實(shí)現(xiàn)迭代
let arr = ['aa','bb','cc']
function fn(temp){ //外部函數(shù)的返回值是閉包
let i = 0
//定義閉包:迭代獲取數(shù)組元素并返回
return function(){
return temp[i++] || '數(shù)組已經(jīng)遍歷結(jié)束'
}
}
let f1 = fn(arr)
console.log(f1()) //aa
console.log(f1()) //bb
console.log(f1()) //cc
console.log(f1()) //數(shù)組已經(jīng)遍歷結(jié)束
(8)、首次區(qū)分(相同的參數(shù),函數(shù)不會(huì)重復(fù)執(zhí)行)
var fn = (function(){
var arr = [] //用來(lái)緩存的數(shù)組
return function(val){
if(arr.indexOf(val) == -1){ //緩存中沒(méi)有則表示需要執(zhí)行
arr.push(val) //將參數(shù)push到緩存數(shù)組中
console.log('函數(shù)被執(zhí)行了',arr); //這里寫(xiě)想要執(zhí)行的函數(shù)
} else {
console.log('此次函數(shù)不需要執(zhí)行');
}
console.log('函數(shù)調(diào)用完打印一下,方便查看緩存的數(shù)組:',arr);
}
})()
fn(10)
fn(10)
fn(1000)
fn(20)
fn(1000)
注意
(1)搞清除誰(shuí)是閉包函數(shù)
(2)分清楚閉包的返回值、外部函數(shù)的返回值
閉包是什么:閉包是一個(gè)函數(shù)(一個(gè)作用域可以訪問(wèn)另外一個(gè)函數(shù)的局部變量)。
閉包的作用是什么:延伸變量的作用范圍。
沒(méi)有產(chǎn)生閉包,因?yàn)椴](méi)有局部變量,所以訪問(wèn)到的是全局變量
The Window
let name = 'The Window'
let object = {
name: 'My Object',
getNameFunc(){
return function(){
return this.name
}
}
}
let f = object.getNameFunc()
console.log(f()) //The Window
產(chǎn)生了閉包:因?yàn)?this 在函數(shù)內(nèi)部被賦值給了 that,指向的是 object 這個(gè)對(duì)象。
let name = 'The Window'
let object = {
name: 'My Object',
getNameFunc(){
let that = this
return function(){
return that.name
}
}
}
let f = object.getNameFunc()
console.log(f()) //My Object
使用閉包的注意點(diǎn)
1)由于閉包會(huì)使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗很大,所以不能濫用閉包,否則會(huì)造成網(wǎng)頁(yè)的性能問(wèn)題,在IE中可能導(dǎo)致內(nèi)存泄露。解決方法是,在退出函數(shù)之前,將不使用的局部變量全部刪除。
2)閉包會(huì)在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值。所以,如果你把父函數(shù)當(dāng)作對(duì)象(object)使用,把閉包當(dāng)作它的公用方法(Public Method),把內(nèi)部變量當(dāng)作它的私有屬性(private value),這時(shí)一定要小心,不要隨便改變父函數(shù)內(nèi)部變量的值。
讀到這里,這篇“es6有沒(méi)有閉包”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。