Javascript Apply & Call
YehYeh\'s Notepad yehyeh@gmail.com 

Javascript

Javascript Apply & Call

  • this是執行情境(Execution Context)的一個屬性
  • 在執行函式時,this的值與函式的值相對應
  • this
    var id = 'Global Var';
    var obj1 = { id : 'OBJ1',
                 // 函式宣告在obj1中,this對應到obj1
                 showID: function(){ alert( this.id );}  
          };
    
    var obj2 = { id : 'OBJ2' };
    
    // 函式宣告在全域作用域,this對應到全域情境
    var showID = function(){	
        alert( this.id );
    };
    
    showID();       //顯示 Global Var
    obj1.showID();  //顯示 OBJ1
    
  • apply & call
    • apply和call的功能都是使用第一個傳入的引數的情境和作用域來執行函式
      • 所以this的值會依傳入的第一個引數而變化
    • apply和call內建在函式的原型(Prototype)中,只要是函式,就可以執行apply和call
      • Function.prototype.apply
      • Function.prototype.call
    • 語法
      • apply
        • fun.apply(thisArg [, argsArray])
      • call
        • fun.call(thisArg[, arg1[, arg2[, ...]]])
    • 使用call來改變函式作用的對象
      var id = 'Global Var';
          var obj1 = { id : 'OBJ1', 
                       showID: function(){ alert( this.id );} 
                     }; 
          var obj2 = { id : 'OBJ2' };
          var showID = function(){
          alert( this.id );
      };
      		
      showID.call(obj1);      // 顯示 OBJ1
      obj1.showID.call(obj2);	// 顯示 OBJ2
      
    • 差異
      • apply和call的第1個參數是必要的且相同
      • apply最多有2個參數,第2個引數是陣列
      • call至少要有1個參數,沒有固定的參數數量
    • 使用時機
      • applycall都用在函式的this不是固定作用域時
      • 當函式的引數個數為固定數量時,通常使用call
        • 使用call
          var obj1 = {
              z : 3,
              add : function(x, y){
                  alert( x + y + this.z);
              }
          };
          
          var obj2 = { z : 5 };
          
          obj1.add(1, 2);              // 6 = 3 + 1 + 2
          obj1.add.call(obj1, 1, 2);   // 6 = 3 + 1 + 2
          obj1.add.call(obj2, 1, 2);   // 8 = 5 + 1 + 2	
          
      • 當函式的引數個數為變動數量時,通常使用apply
        • 使用apply
          var obj1 = { z : 1 };
          var obj2 = { z : 5 };
          
          var add2 = function(m, n){
              alert( this.z + m + n);
          };
          
          var add4 = function(m, n, o, p){
              alert( this.z + m + n + o + p);
          };
          
          var dispatch = function(obj, method, args){
              method.apply(obj, args);
          };
          
          dispatch( obj1, add2, [2, 3]);  // 6 = 1 + 2 + 3
          dispatch( obj2, add2, [2, 3]);  // 10 = 5 + 2 + 3
          
          dispatch( obj1, add4, [2, 3, 4, 5]);  // 15 = 1 + 2 + 3 + 4 + 5
          dispatch( obj2, add4, [2, 3, 4, 5]);  // 19 = 5 + 2 + 3 + 4 + 5	
          

Reference: