返回
call, apply, bind 混淆?拿去手撕吧,隔壁大妈都懂!
前端
2024-01-21 09:10:16
你听说过借鸡生蛋 的故事吗?它的原理和 JavaScript 中的 call、apply、bind 方法非常相似。今天,我们就来把这个过程手撕成碎片,让隔壁大妈都能看懂!
一、借鸡生蛋:JavaScript 版
1. 借鸡(挂载方法)
就像借鸡一样,我们先把方法挂载到一个对象上:
const obj = {
name: 'Tom',
sayHello: function() {
console.log(`Hello, my name is ${this.name}`);
}
};
2. 生蛋(执行方法)
现在,我们让鸡(方法)生蛋(执行):
obj.sayHello(); // Hello, my name is Tom
3. 还鸡(删除方法)
生完蛋后,我们就把鸡(方法)还回去:
delete obj.sayHello;
二、call、apply、bind 的魔法
call、apply、bind 这三个方法就像借鸡生蛋 中的中间人,它们可以帮助我们实现借鸡、生蛋、还鸡的过程:
1. call
// 借鸡
obj.sayHello.call({ name: 'Jerry' }); // Hello, my name is Jerry
// 生蛋
obj.sayHello.call({ name: 'Jack' }, 'world'); // Hello, world
2. apply
// 借鸡
obj.sayHello.apply({ name: 'Mary' }); // Hello, my name is Mary
// 生蛋
obj.sayHello.apply({ name: 'Lucy' }, ['world']); // Hello, world
3. bind
// 借鸡
const boundHello = obj.sayHello.bind({ name: 'John' });
// 生蛋
boundHello(); // Hello, my name is John
// 还鸡
boundHello.apply({ name: 'Tim' }); // Hello, my name is Tim
三、区别与妙用
1. 参数传递
- call 和 apply 可以传递参数,而 bind 只能传递借鸡时需要的参数,生蛋时无法再传递参数。
- apply 的第二个参数必须是数组,而 call 可以直接传递参数。
2. 返回值
- call 和 apply 返回执行方法后的返回值。
- bind 返回一个新的函数,该函数可以多次调用,每次调用都使用最初借鸡时传递的参数。
妙用:
- 借鸡生蛋: 用 call、apply、bind 绑定方法到不同的对象,让这些对象执行不同的操作。
- 延迟执行: 用 bind 创建一个新函数,该函数可以延迟执行,传递不同的参数。
- 部分应用: 用 bind 固定一部分参数,生成一个新的函数,该函数只需要传递剩余的参数即可。
四、隔壁大妈也能懂的例子
小明家有一只母鸡,小红想借来生蛋。
- call: 小明把母鸡借给小红,小红用母鸡生了鸡蛋,鸡蛋是小红的(因为 call 改变了 this 指向)。
- apply: 小明把母鸡借给小红,小红用母鸡生了鸡蛋,鸡蛋是小明的(因为 apply 不改变 this 指向)。
- bind: 小明把母鸡借给小红,小红用母鸡生了鸡蛋,鸡蛋是小红的,但是小红可以随时借母鸡生鸡蛋(因为 bind 返回了一个新的函数)。
现在,你懂了吗?隔壁大妈都懂哦!