概念
**apply call 和bind**
允许为不同的对象分配和调用属于一个对象的函数/方法。同时它们可以改变函数内 this 的指向。
区别
- apply 和 call 接收的参数形式不同;
- apply 和 call 都是直接调用函数并得到函数执行结果,而 bind 会返回待执行函数,需要再次调用。
使用
const parent = {
name: 'parent',
sayPerson (age, addr) {
return { name: this.name, age, addr }
}
}
const person = parent.sayPerson(60, 'shenzhen');
// {name: "parent", age: 60, addr: "shenzhen"}
const son = { name: 'son' }
const callPerson = parent.sayPerson.call(son, 26, 'shenzhen');
// {name: "son", age: 26, addr: "shenzhen"} (可接收多个参数)
const applyPerson = parent.sayPerson.apply(son, [26, 'shenzhen']);
// {name: "son", age: 26, addr: "shenzhen"} (接收数组)
const sayPersonFn = parent.sayPerson.bind(son, 26, 'shenzhen');
const bindPerson = sayPersonFn();
// {name: "son", age: 26, addr: "shenzhen"} (return 一个函数)
简单实现
-
call&apply:
Function.prototype.myCall = function(context=window){
context.fn = this //函数的调用者 => 被借用的函数 this:被借用的函数
const args = [...arguments].slice(1) //传递的参数
const result = context.fn(...args) //执行借用到的函数
delete context.fn //第一步为myCall添加了被借用对象的方法,用完应当删除
return result //return 执行结果
}
Function.prototype.myApply = function(context){
context.fn = this
const args = [...arguments][1] //区别
const result = context.fn(...args)
delete context.fn
return result
}
-
bind:
Function.prototype.myBind = function (...args) {
// 实际就是多包了层待执行函数
return () => {
return this.applyFn(args[0], (args || []).slice(1));
}
}