回顧前面 Execution Context的概念,test 與 inner()存於 Execution Context clo() 中,
照理說在return 時,Execution Context clo()而隨即pop,但在以下案例中,
依然會呈現 outout : 1,這就是 Closure 基礎的概念。
function clo() {
var test = 1;
function inner() {
console.log(test);
}
return inner;
}
var inner = clo();
inner();
// outout : 1
function 能夠存取的範圍包含其內含以及往外推,clo( inner() )
正常的 GC 機制會釋放不再使用的記憶體,但為了保留函式正常存取其範圍,不做記憶體回收。
test 永遠被存在 inner() 中 -> closure
call、apply -> 回傳執行結果
bind -> 回傳綁定參數後的原函數
call & apply
直接呼叫 function
var sui = {
birth: 1998,
countAge: function(country){
if(country === 'Taiwan'){
var age = 2020 - this.birth;
var isFullAge = age >= 18;
console.log(age, isFullAge);
}else if(country === 'Canada'){
var age = 2020 - this.birth;
var isFullAge = age >= 19;
console.log(age, isFullAge);
}
}
}
sui.countAge('Taiwan')
// output : 22 true
// use call method to call sui's function by another object
var jay = {
birth: 2002
}
sui.countAge.call(jay, 'Canada');
// output : 18 false
// apply 用法相近,只是參數是透過 array
bind
並非直接呼叫,而是複製 (稍稍調整 call & apply )
var sui = {
name: 'sui',
birth: 1998,
countAge: function(country, gender){
if(country === 'Taiwan'){
var age = 2020 - this.birth;
var isFullAge = age >= 18;
if(isFullAge & gender === 1){
console.log(this.name + ' will serving in the Taiwanese Army');
}else{
console.log(this.name + ' don\'t neet to serve in the Taiwanese Army now');
}
}else if(country === 'Canada'){
var age = 2020 - this.birth;
var isFullAge = age >= 19;
console.log(age, isFullAge);
}
}
}
// copy the function by bind method and set country to Taiwan
var suiTaiwan = sui.countAge.bind(sui, 'Taiwan');
suiTaiwan(1); // output : sui will serving in the Taiwanese Army
var marry = {
name: 'marry',
birth: 2002
}
// copy the function of sui by bind method and set country to Taiwan
var marryTaiwan = sui.countAge.bind(marry, 'Taiwan');
marryTaiwan(0); //marry will serving in the Taiwanese Army
bind 的 sample 寫得好爛阿
果然還不到可以自己寫出清楚sample的程度,想改寫課程的卻寫的一蹋糊塗
課程 : https://www.udemy.com/course/the-complete-javascript-course/
來源 :
https://blog.techbridge.cc/2018/12/08/javascript-closure/
https://cythilya.github.io/2018/10/22/closure/
https://medium.com/@realdennis/javascript-%E8%81%8A%E8%81%8Acall-apply-bind%E7%9A%84%E5%B7%AE%E7%95%B0%E8%88%87%E7%9B%B8%E4%BC%BC%E4%B9%8B%E8%99%95-2f82a4b4dd66