在JavaScript中,函数是一种特殊的对象,它们可以作为参数传递给其他函数,也可以作为对象的属性或方法。函数的执行上下文(this指向)取决于它是如何被调用的,而不是它是如何被定义的。这意味着同一个函数在不同的对象上调用时,可能会有不同的行为。为了控制函数的执行上下文,JavaScript提供了三个方法:call、apply和bind。这三个方法的作用和区别是什么呢?我们来一 一了解一下。
call方法
call方法可以让一个函数在指定的对象上执行,也就是改变函数的this指向。call方法接受两个或多个参数,第一个参数是要绑定的对象,后面的参数是要传递给函数的实参。例如:
// call可以调用函数
function fun(){
console.log('hello world')
}
fun.call() // hello world
// call可以改变this的指向
var cat = {
name: '猫',
sayName: function () {
console.log('我是' + this.name)
},
eat: function (food1, food2) {
console.log('我喜欢吃' + food1 + food2)
}
}
var dog = {
name: '狗'
}
cat.sayName.call(dog) // 我是狗
cat.eat.call(dog, '骨头', '火腿') // 我喜欢吃骨头火腿
可以看到,通过call方法,我们可以把dog这个对象传给cat。这样,我们就可以复用同一个函数,而不需要为每个对象写一个单独的方法。
apply方法
apply方法和call方法类似,也可以让一个函数在指定的对象上执行,并改变函数的this指向。apply方法只接受两个参数,第一个参数是要绑定的对象,第二个参数是要传递给函数的实参数组。例如:
// call可以改变this的指向
var cat = {
name: '猫',
sayName: function () {
console.log('我是' + this.name)
},
eat: function (food1, food2) {
console.log('我喜欢吃' + food1 + food2)
}
}
var dog = {
name: '狗'
}
cat.eat.apply(dog, ['骨头', '罐头']) // 我喜欢吃骨头罐头
可以看到,通过apply方法,我们可以把dog传递给cat,并且传递不同的实参数组。apply方法通常用于传递可变数量的参数,或者将一个数组拆分为多个参数。
bind方法
bind方法和call、apply方法不同,它不会立即执行一个函数,而是返回一个新的函数,这个新的函数的this指向被绑定到指定的对象。bind方法也接受两个或多个参数,第一个参数是要绑定的对象,后面的参数是要传递给函数的实参。例如:
// call可以改变this的指向
var cat = {
name: '猫',
sayName: function () {
console.log('我是' + this.name)
},
eat: function (food1, food2) {
console.log('我喜欢吃' + food1 + food2)
}
}
var dog = {
name: '狗'
}
cat.eat.bind(dog, '骨头', '罐头')()
可以看到,通过bind方法,我们可以看到bind的用法和call很相似。bind方法通常用于创建柯里化(currying)函数或者延迟执行(lazy evaluation)函数。
总结
call、apply和bind方法都可以改变函数的执行上下文(this指向),但它们有以下区别:
1、返回值的区别:call、apply会直接调用;bind不会直接调用,会作为一个返回值返回一个函数,然后才能调用
2、传参的区别:apply需要传入一个数组, call和bind需要分开传参
这三个方法都是JavaScript中非常重要的概念,它们可以让我们更灵活地控制函数的行为,提高代码的复用性和可读性。
往期精彩:
1、v-bind 和 v-model 的区别:你真的懂了吗?
3、google突然改变规则,在Google Play下架了使用uni-app开发的 App
评论区