iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 18
1
Modern Web

用30天了解javascript系列 第 18

[用30天了解javascript]Day18.閉包

閉包定義

  • 是函式裡面定義另外一個函式(巢狀函式)
  • 將外層變數包在內層使用,變數可以不被釋放,可重複被使用不互相影響
  • 可保護存入變數不被外部修改
  • 使用時需要注意,以免造成佔用記憶體的問題,最好使用完畢能解除引用(設為null),讓GC可以回收。

閉包寫法

一般寫法

num在全域,有可能會不小心改到num變數

var num = 0;
function numSum(){
	num++;
	return num;
}
console.log(numSum()); //1
console.log(numSum()); //2

//在這給變數num值等於10時
var num = 10;
console.log(numSum()); //11
console.log(numSum()); //12

閉包寫法

function numValue(){
	var num = 0;
	return function(val){
		num += val;
		return num;
	}
}
console.log(numValue()(10)); //10
//numValue()是表達式 會回傳另外一個函式
//numValue()(10)後面的括號會執行另一個函式,印出來是10

var countTotal = numValue();
console.log(countTotal(10)); //10
console.log(countTotal(10)); //20
//num會一直去取用上層num=0,所以記憶體不會被釋放掉,因此可以不斷的觸發countTotal(),數值也會一直累加

var countTotal2 = numValue();
console.log(countTotal2(20)); //20
console.log(countTotal2(20)); //40
console.log(countTotal2(20)); //60

//countTotal()、countTotal()都是獨立出來的,可執行屬於自己的函式並用自己的變數

函式工廠及私有方法

函式工廠

function numValue(){
	var num = 0;
	return function(val){
		num += val;
		return num;
	}
}

var countTotal = numValue();
console.log(countTotal(10)); //10
console.log(countTotal(10)); //20

countTotal每次執行,只會執行內部函式,記憶體沒有釋放,num變數會一直不斷被更新,有點像工廠一樣,一直做相同工作,因此稱為函式工廠

私有方法

function numValue(initValue){
	var num = initValue;
	return {
		increase: function(val){
			num += val;
			return num;
		},
		decrease: function(val){
			num -= val;
			return num;
		},
		value: function(){
			return num;
		}
	}
}

var countTotal = numValue(1000);
countTotal.increase(100); //1100
countTotal.decrease(500); //600
countTotal.value(); //600

countTotal = null; //解除引用

私有方法不是只有一個方法,透過私有方法將結果傳入物件,對初始值做不同操作


上一篇
[用30天了解javascript]Day17.立即函式(IIFE)
下一篇
[用30天了解javascript]Day19.this
系列文
用30天了解javascript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Season
iT邦研究生 4 級 ‧ 2020-09-18 09:15:02

您好 文章最下面私有方法

function numValue(initValue){
	var num = initValue;
	return {
		increase: function(val){
			num += val;
			return num;
		},
		decrease: function(val){
			num -= val;
			return num;
		},
		value: function(){
			return num;
		}
	}
}

var countTotal = numValue(1000);
countTotal.increase(100); //1100
countTotal.decrease(500); //500
countTotal.value(); //600

countTotal.decrease(500); //500
是否應該是
countTotal.decrease(500); //600

sunny iT邦新手 1 級 ‧ 2020-09-18 11:17:04 檢舉

是的,沒錯 謝謝您

我要留言

立即登入留言