一直对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的调用类似,只需要把数组换成逗号分隔的单个参数即可。如果各位有其它使用方式或者发现问题,烦请指正赐教。
原文:http://www.cnblogs.com/bulusli/p/4381544.html