天天看點

js閉包的了解(詳細)及應用

閉包就是能夠通路其他函數内部變量的函數,為什麼這麼說呢,下面舉一些例子

由于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>
           
js