1. 程式人生 > >JavaScript中的call、apply、bind用法

JavaScript中的call、apply、bind用法

這三種都是用來明確指定 this 關鍵字所指物件到底是誰。

Function.prototype.call()

call() 方法呼叫一個函式, 其具有一個指定的this值和分別地提供的引數(引數的列表)。

語法 fun.call(thisArg, arg1, arg2, ...)

thisArg:在fun函式執行時指定的this值。
需要注意的是,指定的this值並不一定是該函式執行時真正的this值,如果這個函式處於非嚴格模式下,則指定為null和undefined的this值會自動指向全域性物件(瀏覽器中就是window物件),同時值為原始值(數字,字串,布林值)的this會指向該原始值的自動包裝物件。

arg1, arg2, ...:指定的引數列表。

例子:

function greet() {
  var reply = this.person + ' Is An Awesome ' + this.role
  console.log(reply);
}

var i = {
  person: 'Romeo', 
  role: 'Javascript Developer'
};

greet.call(i); // Romeo Is An Awesome Javascript Developer

Function.prototype.apply()

apply() 方法呼叫一個具有給定this值的函式,以及作為一個數組(或類似陣列物件)提供的引數。
注意:call()方法的作用和 apply() 方法類似,區別就是call()方法接受的是引數列表,而apply()方法接受的是一個引數陣列。

語法 func.apply(thisArg, [argsArray])

thisArg 可選的,在 func 函式執行時使用的 this值。
請注意,this可能不是該方法看到的實際值:如果這個函式處於非嚴格模式下,則指定為 nullundefined 時會自動替換為指向全域性物件,原始值會被包裝。

argsArray 可選的,一個數組或者類陣列物件,其中的陣列元素將作為單獨的引數傳給func函式。還可以使用陣列字面量(array literal),例如fun.apply(this, [0,1,2])
如果該引數的值為 nullundefined,則表示不需要傳入任何引數。從ECMAScript 5 開始可以使用類陣列物件。

例子:

var numbers = [5, 6, 2, 3, 7];
var max = Math.max.apply(null, numbers);
console.log(max);
// expected output: 7

var array = ['a', 'b'];
var elements = [0, 1, 2];
array.push.apply(array, elements);
console.info(array); // ["a", "b", 0, 1, 2]

Function.prototype.bind()

bind()方法建立一個新的函式, 當這個新函式被呼叫時this鍵值為其提供的值,其引數列表前幾項值為建立時指定的引數序列。

語法 fun.bind(thisArg[, arg1[, arg2[, ...]]])

thisArg
呼叫繫結函式時作為this引數傳遞給目標函式的值。 如果使用new運算子構造繫結函式,則忽略該值。當使用bind在setTimeout中建立一個函式(作為回撥提供)時,作為thisArg傳遞的任何原始值都將轉換為object。如果沒有提供繫結的引數,則執行作用域的this被視為新函式的thisArg
arg1, arg2, ...
當繫結函式被呼叫時,這些引數將置於實參之前傳遞給被繫結的方法。

例子:
建立一個函式,無論怎麼呼叫都有同樣的this

this.x = 9; 
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 返回 81

var retrieveX = module.getX;
retrieveX(); // 返回 9, 在這種情況下,"this"指向全域性作用域

// 建立一個新函式,將"this"繫結到module物件
// 新手可能會被全域性的x變數和module裡的屬性x所迷惑
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81