apply、call和bind可以改变this的指向,并且可以把方法借给其它对象使用
例如:a.apply(b,[3,2]);//this指向由a变为b, a的方法借给b使用
1. call、apply与bind的差别
call和apply改变了函数的this上下文后便执行该函数,而bind则是返回改变了上下文后的一个函数。call和bind的参数都是一个个传的,apply的参数是以数组的形式传入的;
2. call、apply的区别
call、apply这两个方法都是定义在函数对象的原型上的(Function.prototype),call和apply方法的作用都是改变函数的执行环境;他们俩之间的差别在于参数的区别,call和apply的第一个参数都是要改变上下文的对象,而call从第二个参数开始以参数列表的形式展现,apply则是把除了改变上下文对象的参数放在一个数组里面作为它的第二个参数。
示例1:
let arr1 = [1, 2, 19, 6];
//例子:求数组中的最值
console.log(Math.max.call(null, 1,2,19,6)); // 19
console.log(Math.max.call(null, arr1)); // NaN
console.log(Math.max.apply(null, arr1)); // 19 直接可以用arr1传递进去
3. call与apply的区别
call和apply方法的作用都是改变函数的执行环境,第一个参数传入上下文执行环境,然后传入函数执行所需的参数。传入call的参数只能是单个参数,不能是数组。apply可传入数组。
示例2:
function fn() {
console.log(this);
}
// apply方法结果同下
fn.call(); // 普通模式下this是window,在严格模式下this是undefined
fn.call(null); // 普通模式下this是window,在严格模式下this是null
fn.call(undefined); // 普通模式下this是window,在严格模式下this是undefined
call、apply与bind的调用示例
var person1={
name:"小花",
gender:"女",
age:18,
introduce:function(hobby1,hobby2){
console.log("我的爱好是"+hobby1+"、"+hobby2)
}
}
var person2={
name:"小明",
gender:"男",
age:20
}
//call会马上执行调用,多个参数时要一个一个传
person1.introduce.call(person2,"羽毛球","篮球");
//apply也会马上执行调用,参数以数组的形式传入
person1.introduce.apply(person2,["羽毛球","篮球"]);
//bind不会马上执行,它返回的仍然是一个函数,因此后面还需要()来进行调用;
//因为它返回的是一个函数,所以我们的参数也可以在后面调用函数的时候再传
person1.introduce.bind(person2,"羽毛球","篮球")();
person1.introduce.bind(person2)("羽毛球","篮球");
如果把参数以数组列表的形式传入call和bind,那么它就会默认把整个数组当成一个参数;如果将数组拆成多个参数传给apply,那么它就会报错!
应用
- 将伪数组转化为数组(含有length属性的对象,dom节点, 函数的参数arguments)
js中的伪数组(例如通过document.getElementsByTagName获取的元素、含有length属性的对象)具有length属性,并且可以通过0、1、2…下标来访问其中的元素,但是没有Array中的push、pop等方法。就可以利用call,apply来转化成真正的数组,就可以使用数组的方法了
- 数组拼接,添加
- 判断变量类型
- 利用call和apply做继承
- 多继承
应用的相应示例去下面参考链接一查看