閉包就是能夠通路其他函數内部變量的函數,為什麼這麼說呢,下面舉一些例子
由于js作用域是一層一層下來的,内部函數可以通路外部變量,但外部函數卻不能通路到内部變量,基于上面的例子就是func()函數可以通路foo()函數内部的變量,如vable,但foo()函數卻不能通路到func()函數内部的變量,而閉包則可以解決這個問題。
這個時候func()函數就是一個閉包。
function foo(){
var vable = '函數foo中的變量';
function func(){
alert(vable);
}
return func; //func被外部函數作為傳回值傳回了,傳回的是一個閉包
}
閉包:func()可以讀取foo()中的變量,隻要把func()作為傳回值,就可以在foo()外讀取foo()内部變量。
有些人可能就會問,要想通路foo()中的變量vable,直接在foo()return vable不就可以了嗎,但閉包的定義是函數,而不是變量,而且函數要比變量在使用方面靈活的多,是以閉包的用處更豐富。
閉包的作用:1.讀取函數内部的變量;2.這些變量的值始終保持在記憶體中,不會在外層函數調用後被自動清除。
閉包的優缺點:
優點:為私有變量提供了一塊獨立的作用域,可以重複使用變量而不會造成變量污染
缺點:記憶體消耗大,容易造成網頁性能問題和記憶體的洩漏
閉包實作在函數外讀取到函數内的變量的原因:
foo()是func()的父函數,func()被賦給了一個全局變量foo(),func()始終存在記憶體中,func()的存在依賴foo(),是以foo()也始終存在記憶體中,不會在調用結束後,被垃圾回收機制回收。
下面舉一個閉包的應用場景:setTimeout
有些函數規定沒有參數或者某些參數(如函數)不能攜帶參數(變量)
如原生的setTimeout傳遞的第一個函數不能帶參數、vue中computed計算屬性中的變量不能接收傳遞給它的參數等…
//原生的setTimeout傳遞的第一個函數不能帶參數
setTimeout(function(param){
alert(param)
},1000)
//通過閉包可以實作傳參效果
function func(param){
return function(){
alert(param)
}
}
var f1 = func(1);
setTimeout(f1,1000);
<template>
<div :style="{'color':colorText(item.message)}"></div>
</template>
<script>
export default{
computed:{
colorText(){
//在html中傳遞給total的參數在這裡接收,這裡用到的原理就是js閉包傳值
return function (message) {
switch (message) {
case '成功': return 'rgba(74,74,74,1)';
case '失敗': return 'rgba(244,66,66,1)';
case '等待': return 'rgba(162,162,162,1)';
}
}
}
}
}
</script>