你的位置:首页 > Java教程

[Java教程]javascript的apply和call方法的使用详解


一直对javascript的apply和call方法的使用比较模糊,前段时间在研究angularjs的源代码时,发现这两个方法非常的强大,使用的场景非常多,这里做个总结。

apply和call都是对某个方法的应用,区别在于apply有两个参数:apply(obj,args),其中obj为方法应用的对象,args为参数数组;call有多个参数,call(obj,arg1,arg2,arg3......),obj和apply的obj一样,而参数则是用逗号隔开,有多少个参数就传多少个。下面以apply为例,需要注意的是apply的第二个参数必须为数组,否则会报错。

 

1.obj为null、undefined、bool值、0、this、window等的时候,相当于调用方法自身。

function test(arg) {
console.log(arg);
}

分别调用test.apply(null,[1,2,3]),test.apply(undefined,[1,2,3]),test.apply(false,[1,2,3]),test.apply(true,[1,2,3]),

test.apply(0,[1,2,3]),test.apply(this,[1,2,3]);

输出结果都为1。

ps:test函数只有一个参数,所以即使传入的数组参数多于一个,也只会取第一个,其它的被忽略。

 

2.obj为不存在的对象时,会报错。仍然以上一个函数为例。

调用test.apply(ffff,[1,2,3]),则直接报错。

输出:Uncaught ReferenceError: ffff is not defined。

 

3.obj为函数时,如XXX.apply(obj,args),意为调用XXX函数。

function test1(arg) {
console.log("test1 " + arg);
}

function test2(arg1, arg2) {
console.log(arg1 + " " + arg2);
}

 

 

调用test1.apply(test2, [1, 2, 3]);

 

输出:test1 1。

 

可以看见,其实就是将参数传给test1然后调用test1。

 

4.当obj为对象时,obj对象会替代XXX.apply中的XXX函数的this,将this所拥有的属性变成obj对象自己的属性。

 

例1:

function Test1() {
console.log("test1 ");

this.a = 1;
this.b = 2;

}

var c ={};

Test1.apply(c, []);

 

此时的c对象为{a:1,b:2}。

 

例2:

function Test1() {
console.log("test1 ");

this.a = 1;
this.b = 2;
}

Test1.prototype = {c: 3, d: 4};

var c = Test1.prototype;
Test1.apply(c, []);

 

此时的c对象为{a:1,b:2,c:3,d:4}。

 

另外,如果函数有返回值,给apply的结果赋一个变量即可获得。

function test1() {
console.log("test1");

return function () {
console.log("return function");
}
}

var back = test1.apply(null, []);
back();

输出:return function。

 

目前对apply的了解就这么多,call的调用类似,只需要把数组换成逗号分隔的单个参数即可。如果各位有其它使用方式或者发现问题,烦请指正赐教。