iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 25
0
自我挑戰組

前端我來了 - 30天 JavaScript 從無到有 系列 第 25

[30天 JavaScript 從無到有 Day 25] Closure & call / apply / bind

閉包(Closure)

回顧前面 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 -> 回傳執行結果
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 寫得好爛阿/images/emoticon/emoticon02.gif/images/emoticon/emoticon02.gif/images/emoticon/emoticon02.gif
果然還不到可以自己寫出清楚sample的程度,想改寫課程的卻寫的一蹋糊塗/images/emoticon/emoticon02.gif

課程 : 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


上一篇
[30天 JavaScript 從無到有 Day 24] Object and Function
下一篇
[30天 JavaScript 從無到有 Day 26] Module Pattern
系列文
前端我來了 - 30天 JavaScript 從無到有 30

尚未有邦友留言

立即登入留言