call函数的实现
2021-01-05 本文已影响0人
tenro
原理
let person = {
name: 'pill Gates',
fullName: function(){
console.log(this.name)
}
}
/**
fullName是person自己的方法
所以this指向的是自己本身
故下输出: 'pill Gates'
*/
person.fullName()
简化实现call方法
let person = {
fullName: function(){
return this.firstName + this.lastName
}
}
let person1 = {
firstName: 'bill',
lastName: 'gates'
}
/**
在函数Function的原型上添加一个toCall的方法
userObj 是要调用的对象
通过this的转换将 ‘被调用者’ 的方法转嫁到userObj上,但是参数依然原来的
*/
Function.prototype.toCall = function(userObj, ...args){
userObj.fn = this //当前这个this是谁调用toCall这个方法它就指向谁
return userObj.fn(...args)
}
/**
将person.fullName当中this指向person1,
故输出 'bill gates'
*/
person.fullName.toCall(person1)
优化实现call方法(上面的核心是toCall, 其他都是配角,所以优化就是优化toCall内部结构)
Function.prototype.toCall = function(userObj, ...args){
const fn = Symbol('fn') //声明独一属性,防止覆盖内部属性
userObj = userObj || window // 若没有传入this, 默认绑定window对象
userObj[fn] = this // this指向调用call的对象,即我们要改变this指向的函数
const result = userObj[fn](...args) // 执行当前函数
delete userObj[fn] // 删除我们声明的fn属性
return result
}