这三剑客的使用容易忘记其原理,总结此笔记加强巩固,有不足之处希望评论指出
1. call使用场景如下:
function people(age,like) {
console.log(`${this.name} 已经 ${age}岁了 喜欢${like}`)
}
const lili = {
name: 'lili',
}
people.call(lili, 12, 'music') // lili 已经 12岁了 喜欢music
上面这波操作可以简单理解成如下:
const lili = {
name: 'lili',
fn: function people(age) {
console.log(`${this.name} 已经 ${age}岁了`)
}
}
people 方法中并没有name属性, 但是通过call,改变了this指向;将people方法挂载到lili这个对象的fn方法上,这样执行fn方法时this指向lili这个对象,所以获得了name, 那么实现自己的myCall 尝试一下
2. 实现myCall
Function.prototype.myCall = function(context) {
// 若第一个参数未传,则this指向window
context = context || window
// 相当于将people方法挂载到lili这个对象上fn方法上
context.fn = this
const args = [...arguments].slice(1)
const result = context.fn(...args)
delete context.fn // 用完就要删除掉
return result
}
people.myCall(lili, 13, 'food') // lili 已经 13岁了 喜欢food
3. apply使用场景
apply 与 call 的差别在于参数的形式不同, 传入参数是数组形式
people.apply(lili, [14, 'sleep']) // lili 已经 14岁了 喜欢sleep
4. 实现myApply
Function.prototype.myApply = function(context) {
context = context || window
context.fn = this
const args = [...arguments][1]
const result = context.fn(...args)
delete context.fn
return result
}
people.myApply(lili, [15, 'read']) // lili 已经 15岁了 喜欢read
以上就是call 和 apply 的实现 ,接下来实现一下bind,它与上面两个有点不同,因为会涉及new 实例操作
5.bind 使用场景
bind绑定并不是绑定即执行, 如下:
people.bind(lili) // 只是绑定,不会执行
// 先绑定 后面再执行
const bindPeople = people.bind(lili,16,'study')
bindPeople() // lili 已经 16岁了 喜欢study
由上面操作可以看出bind 返回的是一个函数,下面实现一下
6.实现myBind
Function.prototype.myBind = function(context) {
if(typeof this !== 'function') {
throw new TypeError('not a function')
}
const that = this
const args = [...arguments].slice(1)
// 因为存在判断是否是实例化操作,需要具名
let Func = function() {
// 合并参数,类似处理柯理化函数参数
const allArgs = [...args, ...arguments]
if(this instanceof Func) { // 实例化操作
return new that(...allArgs)
} else {
that.apply(context, allArgs)
}
}
return Func
}
const bindPeople1 = people.myBind(lili,17,'travel')
bindPeople1() // lili 已经 17岁了 喜欢travel
const bindPeople2 = people.myBind(lili,18)
bindPeople2('go hiking') // lili 已经 18岁了 喜欢go hiking
// 若为构造函数呢
const BindPeople = people.myBind(lili,19)
people.prototype.love = 'eat'
const a = new BindPeople('study')
console.log(a.love) // eat
待续。。。