js的call()和apply()方法
因为用的比较少,一直对js的call()和apply()理解的不深,最近翻看了[JavaScript The Definitive Guide 6th Edition]算是明白这两方法在干什么了。书中有两段话写的很明白,直接引用并翻译,翻译的不好请见谅:
1. Both methods allow you to explicitly specify the this value for the invocation, which means you can invoke any function as a method of any object, even if it is not actually a method of that object.
翻译:两个方法都允许你显式的指定所调用的函数的this属性,这就是说你可以将任何函数当成任何的"对象的函数"来调用,即使这个对象实际上没有定义这个函数。
继续看第二段:
2. The first argument to both call() and apply() is the object on which the function is to be invoked; this argument is the invocation context and becomes the value of the this keyword within the body of the function.
翻译:call()和apply()的第一个参数用于指定函数在哪个对象上执行;该对象其实是所调用函其实这两个方法都在做一件事:改变函数的this变量的值。
举例更容易看明白:
示例1:
[javascript]
var name = 'out';
function show()
{
this.name = 'in';
this.print = function(){console.log(this.name);}
}
var s = new show();
s.print(); // 1
s.print.call(window); // 2
var name = 'out';
function show()
{
this.name = 'in';
this.print = function(){console.log(this.name);}
}
var s = new show();
s.print(); // 1
s.print.call(window); // 2依次输出:in, out
注释1那行调用print打印的是s对象的name属性,注释2那行因为用call方法改变了this所指的对象,现在是window,因此打印的是window.name,即“out”
示例2:
写一个简单函数如下:
[javascript]
function show()
{
console.log(arguments.slice(1));
}
function show()
{
console.log(arguments.slice(1));
}可以放到chrome的console里执行,然后调用show(),一定会提示你:TypeError: Object #<Object> has no method 'slice',因为arguments对象没有slice方法。
但是若写成这样:
[javascript]
function show()
{
console.log(Array.prototype.slice.call(arguments,1));
}
function show()
{
console.log(Array.prototype.slice.call(arguments,1));
}然后执行show(1,2),一定会打印出[2],这等于让arguments神奇的拥有了slice方法。
当然,call和apply还是有点区别的,主要是传参的方式,可以对比如下:
call(obj, arg1, arg2, ...)
apply(obj, [arg1, arg2, ...]) //传的是数组
补充:web前端 , JavaScript ,