call、apply、bind 的使用

95 阅读2分钟

call、apply、bind 的使用

call方法、apply方法、bind方法,这三个方法很类似。

先学会 call方法 其他两个方法只需要一些小小的改动就可以了。

通俗来讲:一个作用域想使用另一个同级作用域内的变量、函数等,就可以使用 call、apply、bind 方法。

call 方法

call 是一个方法,是函数的方法。

  • call 可以调用函数
  • call 可以改变函数中 this 的指向
  • call 方法第一个参数是改变this指向的对象(写哪个对象就会指向哪个对象),往后的参数就是需要使用的参数了。
// call 可以调用函数
function fun() {
    console.log("hello world");
}
fun.call();	// hello world


// call 可以改变函数中 this 的指向
function fun() {
    console.log(this.name);
}

let cat = {
    name: '喵喵'
}
fun.call(cat);	// 喵喵 

----------------------------
let dog = {
    name: '旺财',
    sayName() {
        console.log("我是" + this.name);
    },
    eat(food) {
        console.log("我喜欢吃" + food);
    }
}

let cat = {
    name: '喵喵'
}

dog.eat("骨头");	// 我喜欢吃骨头
dog.eat.call(cat);	// 我喜欢吃undefined
dog.eat.call(cat, "鱼");	// 我喜欢吃鱼

--------------------
let dog = {
    name: '旺财',
    sayName() {
        console.log("我是" + this.name);
    },
    eat(food1, food2) {
        console.log("我喜欢吃" + food1 +'和' + food2);
    }
}

let cat = {
    name: '喵喵'
}
dog.sayName.call(cat);	// 我是喵喵
dog.eat.call(cat, "鱼", "猫条");	// 我喜欢吃鱼和猫条

apply 方法

apply方法 和 call方法的唯一区别就是,传参不一样。

call方法,第一个参数是this指向的对象,往后是需要的参数

apply方法,第一个参数是this指向的对象,第二个参数是一个数组。

let dog = {
    name: '旺财',
    sayName() {
        console.log("我是" + this.name);
    },
    eat(food1, food2) {
        console.log("我喜欢吃" + food1 +'和' + food2);
    }
}

let cat = {
    name: '喵喵'
}
dog.sayName.apply(cat);	// 我是喵喵
dog.eat.apply(cat, ["鱼", "猫条"]);	// 我喜欢吃鱼和猫条

bind 方法

bind 方法 传参和 call方法 一模一样。

唯一的区别就是,bind方法不会调用函数,会返回一个函数。

let dog = {
    name: '旺财',
    sayName() {
        console.log("我是" + this.name);
    },
    eat(food1, food2) {
        console.log("我喜欢吃" + food1 +'和' + food2);
    }
}

let cat = {
    name: '喵喵'
}

let catEat = dog.eat().bind(cat, '鱼肉', '猫条');
catEat();	// 我喜欢吃鱼肉和猫条

实际应用

这里就使用 call 方法举例。

call方法、apply方法、bind方法 可以实现类的继承。

// 定义一个 Animal 类
function Animal() {
    this.eat = () => {
        console.log("吃东西");
    }
}

// 定义一个 Cat 类
function Cat() {
    Animal.call(this);	// 实现继承 Animal 类
}

let cat = new Cat();
cat.eat();	// 吃东西

call方法、apply方法、bind方法 的好处是,在一个类中可以继承多个类。

// 定义一个 Animal 类
function Animal() {
    this.eat = () => {
        console.log("吃东西");
    }
}

// 定义一个 Bird 类
function Bird() {
    this.fly = () => {
        console.log("飞翔")
    }
}

// 定义一个 Cat 类
function Cat() {
    Animal.call(this);	// 实现继承 Animal 类
    Bird.call(this);	// 实现继承 Bird 类
}

let cat = new Cat();
cat.eat();	// 吃东西
cat.fly();	// 飞翔