JS中的apply()和call()方法

JS中每個函數都包含兩個非繼承而來的方法: apply( ) 和 call( ) 。

這兩個方法的用途都是:在特定的作用域中調用函數,實際上等於設置函數體內this對象的值。


apply( ) 接受兩個參數:一個是在其中運行函數的作用域,另一個是參數數組(既可以是 Array 的實例,也可以是 arguments 對象)。例:

var num1 = 222, num2 = 333, num3 = 444;
function sum(num1, num2, num3){    //求和函數
    return num1 + num2 + num3;
}
function callSum1(num1, num2){
    let num3 = 3;
    let argu = [num1, num2, num3];
    return sum.apply(this, argu);	//sum()函數中可以使用let變量
}
function callSum2(num1, num2, num3){
    return sum.apply(this, arguments);	//arguments傳參
}
function callSum3(num1, num2, num3){
    return sum.apply(this, [num1, num2, num3]);	//傳入數組
}

console.log(callSum1(1, 2));	//6
console.log(callSum2(10, 20, 30));	//60
console.log(callSum3(0, 0, 1));	//1

> callSum1( ) 在執行 sum( ) 函數時傳入了 this 作爲 this 值(因爲是在全局中調用的,所以傳入的就是 window 對象)。

call( ) 接受的第一個參數與 apply( ) 一樣,但後面傳遞給函數的參數必須逐個列舉出來。例:

function sum(num1, num2){
    return num1 + num2;
}
function callSum(num1, num2){
    return sum.call(this, num1, num2);    //必須明確地傳入每一個參數
}
console.log(callSum(1, 2));	//3



這兩個方法主要的用處並不是用來傳參,而是能夠擴充函數賴以運行的作用域

例:

window.color = "red";
var o = { color: "blue" };
function sayColor(){
    console.log(this.color);
}

sayColor();	//red

sayColor.call(this);	//red
sayColor.call(window);	//red
sayColor.call(o);	//blue

> sayColor( ) 在全局環境下定義的,是全局函數,所以在全局作用域中調用它時,輸出 "red"(因爲對 this.color 的求值會轉換成 window.color 的求值)。而 sayColor.call(this) 和 sayColor.call(window) 則是兩種顯式地在全局作用域中調用函數的方式,所以輸出 "red" 。但當函數的執行環境指向 o 時,this.color 的值就爲 "blue" 。

使用 call() 和 apply() 來擴充作用域的最大好處,就是對象不需要與方法有任何耦合關係

看一個例子:

window.num1 = 1;
window.num2 = 2;
var o = { num1: 11, num2: 22 };
var oo = { num1: 111, num2: 222 };
function saySum(){
    console.log(this.num1 + this.num2);
}

saySum();	//3
saySum(this);	//3
saySum(window);	//3
saySum.apply(o);	//33
saySum.call(o);	//33
saySum.apply(oo);	//333

> 函數 saySum( ) 與對象 o 和 oo 之間沒有任何耦合關係,通過 call( ) 或 apply( ) 建立聯繫。

另一個例子:

window.sum1 = function(num1, num2){
    return num1 + num2;
};
var o = { sum1: function(num1, num2){
    return num1 + num2 + 222;
} };
var oo = { sum1: function(num1, num2){
    return num1 + num2 + 333;
} };
function saySum(){
    console.log(this.sum1(1, 2));
}

saySum.apply();	//3
saySum.apply(o);	//225
saySum.apply(oo);	//336

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章