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