call、apply和bind的作用主要是改变一个方法的this对象的指向,call apply bind 都是来自object.prototype的。
具体语法如下:
fn.call(obj [ , arg1 [ , arg2 [ , ..argN ] ] ] );
fn:要改变的函数
obj:改变后this所指向的对象
arg:要传入fn的参数
apply与call的用法相差不大,只是给函数传入参数时为一个数组
fn.apply(obj [ , [argArr] ] );
fn:要改变的函数
obj:改变后this所指向的对象
argArr:要传入fn的参数的数组
案例:
var stu1={name:"tom", showname:function(){ alert(this.name) } };
var stu2={name:"smith"};
stu1.showname();
stu1.showname.call(stu2);
stu1.showname.apply(stu2);
会看到第一次弹出tom 第二次和第三次弹出smith
bind方法和上面两个方法有一点区别,它会返回一个重新绑定this的新函数;
fn.bind(obj);
obj:改变后this所指向的对象
案例:
var stu1={name:"tom", showname:function(){ alert(this.name) } };
var stu2={name:"smith"};
stu1.showname();
var showstu2=stu1.bind(stu2);
showstu2();
会看到第一次弹出tom 第二次弹出smith
灵活使用这三个方法可以在js中借用方法
一个常用的例子是,当对象和数组都是列表类型的数据结构时,对象可以从数组“借用”方法。最常借用的方法是 Array.prototype.slice。
function myFunc(1,2,3,4,5){
//arguments.sort();
//直接这样写会报错,因为函数中的arguments是一个对象而不是一个数组
var args=Array.prototype.slice.call(arguments);
args.sort();
console.log(args);
}
每次都要通过原型调用会有些麻烦,所以可以直接通过字面量的方式来调用数组的一些方法
例如
[].slice.call(arguments);
或者
var join=[].join;
join.call('abc',d);
但是每次调用的时候都要使用call()或者apply()还是会有些麻烦,为了提高代码的可重用性
可以做一下步骤
var slice = Function.prototype.call.bind(Array.prototype.slice);
这样做可能有些难理解,但是只要你掌握了bind call方法就很容易理解了
首先通过bind方法返回一个让Array.prototype.slice调用call方法的函数,
这样在调用slice方法时,传入的参数就是给call传入的参数。
slice( "12345" );
返回一个数组 [1,2,3,4,5]