call与apply的语法:
- fun.call(thisArg[, arg1[, arg2[, ...]]])。thisArg是函数运行时候指定的this,之后是执行函数传入的参数列表。
- fun.apply(thisArg[, argsArray])。thisArg作用同上,不同call的是传入的是一个参数的数组对象。
总结一下call与apply的作用:
- 调用函数。
- 改变this的指向。
最重要的是,我们可以衍生出一个作用:借用,借用,借用。
我们来看一下一个例子:
- 求出数组arr=[1,7,10,5,0]中最大的值,一般可以选择排序或者借个变量判断。当然,我们也会想到Math.max(),但是,这个方法不接受数组,这个时候就可以使用apply去借用这个函数。
var arr=[1,7,10,5,0]
//这里this没有任何意义
Math.max.apply(null,arr)//10
- 再来一个例子,我们知道document.getElementByTagName()获取的是一个类数组对象,不能使用数组的push,pop之类的方法,这时候可以用借用数组的slice(分割数组)的方法进行转化。
//先往页面放几个li
var lis=document.getElementsByTagName('li');
var arrLis = [].slice.call(lis)//或者Array.prototype.slice.call(lis)
console.log(arrLis.length);
arrLis.pop();
console.log(arrLis.length)
效果可看这里
- 又或者我们有一个对象,想要用另一个对象去调用他的属性方法。就可以这样。
function Animal (age){
this.age=age;
}
function Cat(color,age){
this.color=color;
Animal.call(this,age)
}
var cat1 = new Cat('white',2)
console.log(cat1.age)
我们再来说一说bind();
- fun.bind(thisArg[, arg1[, arg2[, ...]]]),thisArg,this的指向(使用new 调用的时候无效),之后的参数是一个参数列表。
bind() 函数会创建一个新函数(称为绑定函数),新函数与被调函数(绑定函数的目标函数)具有相同的函数体(在 ECMAScript 5 规范中内置的call
属性)。当目标函数被调用时 this 值绑定到 bind() 的第一个参数,该参数不能被重写。绑定函数被调用时,bind() 也接受预设的参数提供给原函数。一个绑定函数也能使用new
操作符创建对象:这种行为就像把原函数当成构造器。提供的 this 值被忽略,同时调用时的参数被提供给模拟函数。
现在让我们看个栗子:
- 我们再使用原型对象绑定事件的时候通常都会把this赋值给self,_this...。但是我们可以使用bind()来设置得更好:
//先给页面来个btn;
function Btn (target) {
this.target=target;
this.addEvent();
}
Btn.prototype.addEvent = function(){
this.target.onclick=function(){
//这里的this变成函数外面的this了
console.log(this.target.id)
}.bind(this)
}
new Btn(document.querySelector('#btn'))
最后说一下3者的区别;
前2者call与apply调用函数:func.call(thisArg),func.apply(thisArg)。
而bind与上面2者不同:func.bind(thisArg)();(它的后面多了一个括号,也就是说bind()方法,不能调用函数)