js的call()和apply()方法

因為用的比較少,一直對js的call()和apply()理解的不深,最近翻看瞭[JavaScript The Definitive Guide 6th Edition]算是明白這兩方法在幹什麼瞭。書中有兩段話寫的很明白,直接引用並翻譯,翻譯的不好請見諒:

1. Both methods allow you to explicitly specify the this value for the invocation, which means you can invoke any function as a method of any object, even if it is not actually a method of that object.

翻譯:兩個方法都允許你顯式的指定所調用的函數的this屬性,這就是說你可以將任何函數當成任何的"對象的函數"來調用,即使這個對象實際上沒有定義這個函數。

繼續看第二段:

2. The first argument to both call() and apply() is the object on which the function is to be invoked; this argument is the invocation context and becomes the value of the this keyword within the body of the function.

翻譯:call()和apply()的第一個參數用於指定函數在哪個對象上執行;該對象其實是所調用函其實這兩個方法都在做一件事:改變函數的this變量的值。

舉例更容易看明白:

示例1:

[javascript]
var name = 'out'; 
function show() 

    this.name = 'in'; 
    this.print = function(){console.log(this.name);} 

var s = new show(); 
s.print();  // 1  
s.print.call(window);  // 2 

var name = 'out';
function show()
{
 this.name = 'in';
 this.print = function(){console.log(this.name);}
}
var s = new show();
s.print();  // 1
s.print.call(window);  // 2依次輸出:in, out

註釋1那行調用print打印的是s對象的name屬性,註釋2那行因為用call方法改變瞭this所指的對象,現在是window,因此打印的是window.name,即“out”

示例2:

寫一個簡單函數如下:

[javascript]
function show() 

    console.log(arguments.slice(1)); 

function show()
{
 console.log(arguments.slice(1));
}可以放到chrome的console裡執行,然後調用show(),一定會提示你:TypeError: Object #<Object> has no method 'slice',因為arguments對象沒有slice方法。

但是若寫成這樣:

[javascript]
function show() 

    console.log(Array.prototype.slice.call(arguments,1)); 

function show()
{
 console.log(Array.prototype.slice.call(arguments,1));
}然後執行show(1,2),一定會打印出[2],這等於讓arguments神奇的擁有瞭slice方法。

當然,call和apply還是有點區別的,主要是傳參的方式,可以對比如下:

call(obj, arg1, arg2, …)

apply(obj, [arg1, arg2, …])  //傳的是數組

 

 

You May Also Like