比较call()、apply()和bind()
ECMAScript给所有函数都规定了call()和apply()方法,两个方法作用一致,只是传参形式不同,适用于不同的场景。
比较传参形式
let action={
activity:'eat'
}
function animal(animal1,animal2){
console.log(animal1+' '+this.activity+' '+animal2)
}
animal.call(action,'tiger','rabit')//tiger eat rabit
animal.apply(action,["cat",'fish'])//cat eat fish
animal.bind(action)("lion","goat")//lion eat goat`
可以看到在函数animal中,我们访问的是this.activity,而在函数中并没有activity这个属性,我们正常来讲会沿着作用域链向上寻找有没有这个属性,而animal往上寻找就是window。但是在window中并没有activity这个属性,所以在这里我们利用call(),apply()或者bind()就可以改变this指向,访问到action中的属性。但是几种方法传参是不一样的。
- call()传入的参数是散乱的数据,用于没有特定关系的数据
- apply()传入的参数是一个数组,如果是一个完整的数组,传入就很方便了
- bind()返回的是一个新的函数实例,所以这里当成正常函数使用就好了
在不传第二个参数下的比较
window.color = 'red'
let o = {
color: 'orange'
}
function showColor() {
console.log(this.color)
}
console.log('apply不传参的结果')
showColor.apply(o)//orange
console.log('call不传参的结果')
showColor.call(o)//orange
//apply()和call()都会在改变this指向后立即执行
console.log('bind不传参的结果')
//bind只返回指向了指定this的实例,但是不会执行
showColor.bind(o)//无结果
我们可以看到apply()和call()在不传参情况下的行为表现是一致的。而bind()返回了改变this指向的函数实例,并未执行。
借用函数比较
window.name='myWindow'
var Person1 = function () {
this.name = 'selfName';
}
var Person2 = function () {
this.getname = function () {
console.log(this.name);
}
//相当于执行了一次this.name='selfName',所以才可以在这里访问到自己函数里的属性
Person1.apply(this)
}
var person = new Person2()
//访问的并不是Person1的name,而是自己的name
person.getname(); // selfName
注释已经写得很清楚了,诸君应该都能看懂。分享就到这里了,喜欢的可以麻烦点一个赞。