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              
} 
上一篇下一篇

猜你喜欢

热点阅读