JavaScript之手写call

60 阅读1分钟

call方法

该方法可以传递一个thisArgs参数和一个参数列表,thisArgs 指定了函数在运行期的调用者,也就是函数中的 this 对象,而参数列表会被传入调用函数中。thisArgs 的取值有以下四种情况:

  • 不传,或者传null,undefined, 函数中的 this 指向全局对象,浏览器中指向window,nodejs中指向global
  • 传递另一个函数的函数名,函数中的 this 指向这个函数的引用
  • 传递字符串、数值或布尔类型等基础类型,函数中的 this 指向其对应的包装对象
  • 传递一个对象,函数中的 this 指向这个对象
Function.prototype.myCall = function(ctx,...args){ 
    //确定this指向,使用参数归一化,globalThis在浏览器就是window在node就是global,Object()返回一个包装类
    ctx = ctx === null ||ctx ===undefined ?globalThis:Object(ctx)
    
    //使用Symbol()创建的key永不重复,防止他覆盖传入对象内的现有的值
    const key = Symbol()
    
    //使用Object.defineProperty方法设置key的属性描述为不可枚举
    Object.defineProperty(ctx,key,{
        value:this,
        enumerable:false
    })
    const result  = ctx[key](...args)
    delete ctx[key]
    return result
}


function method(a,b) {
    console.log("args",a,b);
    console.log('this',this)
}

method.myCall(1,2,3)