原生js的call()和apply()一直有点迷糊,最近又碰到这两个方法,好好学习了一下。

先来看一下这两个方法的定义:

call方法:
语法:call(thisObj,Object)
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

apply方法:
语法:apply(thisObj,[argArray])
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
说明:如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。

a、
简单写一段代码来说明一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function a(){
this.name = "I'm A."
this.showName = function(){
console.log(this.name);
}
}

function b(){
this.name = "I'm B."
}

var fnA = new a(); //实例化a
var fnB = new b(); //实例化b
fnA.showName(); //I'm A.

fnA.showName.call(fnB); //I'm B.
//方法b是没有 showName的方法的,但是这里却打印出来了 I'm B.

对照call()的定义,就不难理解了,就是:将fnA对象的showName方法,放到fnB上执行,相当于在fnB对象中添加了一个方法showName。由于实例化,内部this的指向就是函数对象本身,所以就打印来了“I’m B.”的结果。

b、
因为js中函数本身就是对象,所以会有下边这种情况:

1
2
3
4
5
6
7
8
9
function add(a,b){
console.log(a+b);
}

function sub(a,b){
console.log(a-b);
}

add.call(sub,2,3); //5 这里就是add方法覆盖了sub,add.call(sub,2,3) == add(2,3);

那么apply和call的区别就是,apply的参数 第一个同call一样都是thisObj,随后的参数apply必须是数组或者arguments对象,而call的参数则没有限制类型。