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

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