call、apply、bind的基本概念

234 阅读3分钟

call、apply、bind三个都是函数的方法

由于有三个方法,可能会纠结学哪个的时候,这个时候我们就先盯着call学! (学会一个的用法,其他两个用法只有略微的不同...)

call可以调用函数, 并且改变函数中this

来个很简单的小案例:

let dog = {
   name: '旺旺',
   sayName(){   //此时有个方法打印出 name
    console.log('我的名字是'+this.name)
   }
}

let cat = {
  name: '喵喵'
}

dog.sayName()

输出结果:

毫无疑问,名字是旺旺,和喵喵没什么关系

image.png

那我们想让name和喵喵有关系的话, 就得使用call改变this指向喵喵了

很简单, 只需要加一个call就能办到

let dog = {
name: '旺旺',
sayName(){
console.log('我的名字是'+this.name)
}
}

let cat = {
name: '喵喵'
}
dog.sayName.call(cat)   // 不同点

这里我们加了一个call, call的参数直接写 cat 改变this指向

来看打印结果:

image.png

改变成功!

再来一个传参数的小案例:

在原来的基础下再添加一个方法

let dog = {
name: '旺旺',
sayName(){
console.log('我的名字是'+this.name)
},
eat(food){
 console.log('我喜欢吃'+food)
}
}

let cat = {
name: '喵喵'
}

dog.eat('骨头')   // 添加参数

输出结果:

毫无疑问,喜欢吃的是骨头,喵喵还是没什么关系

image.png

继续使用call让 cat 参与进来

let dog = {
name: '旺旺',
sayName(){
console.log('我的名字是'+this.name)
},
eat(food1, food2){  // 注意这儿形参有两个
 console.log('我喜欢吃'+food)
}
}

let cat = {
name: '喵喵'
}

**看这里!!!**
dog.eat.call(cat)
//注意这里有问题的 打印结果为: 喵喵喜欢吃的是undefined
// 因为没有跟参数...

正确传参:
dog.eat.call(cat,'鱼') // 只需要逗号隔开 加参数就可以

如果传两个参数呢?
dog.eat.call(cat,'鱼','肉')  // 往后面在继续加, 

打印结果:

image.png

这是call的的使用 (改变this指向, 以及传参)

再说一下apply()

还是一样的例子用法
与call不同点: 以数组方式去传参,

let dog = {
name: '旺旺',
sayName(){
console.log('我的名字是'+this.name)
},
eat(food1, food2){  // 注意这儿形参有两个
 console.log('我喜欢吃'+food)
}
}

let cat = {
name: '喵喵'
}

看这儿
dog.eat.apply(cat,['鱼','肉'])  // 打印结果 我喜欢吃鱼,肉

打印结果和上面相同就不放图了

接下来再说bind:

bind传参方式与call相同, 不同的是bind不会调用这个函数,而是把函数作为返回值给返回回来;

let dog = {
name: '旺旺',
sayName(){
console.log('我的名字是'+this.name)
},
eat(food1, food2){  // 注意这儿形参有两个
 console.log('我喜欢吃'+food)
}
}

let cat = {
name: '喵喵'
}

看这儿
let bind = dog.eat.bind(cat,'鱼','肉') 把返回值赋值给变量
bind()

打印结果:

image.png

总结:

三个方法相同的地方:

  • 三者都是用来改变函数的this对象的指向的
  • 三者第一个参数都是this要指向的对象,也就是想指定的上下文
  • 三者都可以利用后续参数传参

三个方法不同的地方:

call: 对象.call(对象,'1','2') 依次往后传的方式传参

apply: 把实参以数组方式去传参

bind: 把函数以返回值的形式返回


继承: 子类可以使用父类的方法

//  在这我们有两个函数
function Animal() {
 当代码执行到这儿的时候this发生了改变
   this.test = function () {
   console.log('打印成功')
 }
}

function Cat(){
//只需要这一行代码改变this指向cat 
   Animal.call(this)  
}
需求是调用cat函数 可以使用Animal里面的test和eat方法
let cat = new Cat()
cat.test()  // 打印成功