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[, ...]]])
- apply:
- 使用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個參數,沒有固定的參數數量
- 使用時機
- apply和call都用在函式的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
- 使用call
- 當函式的引數個數為變動數量時,通常使用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
- 使用apply