编辑代码

// bind函数,返回一个新的function
// 实际就是新的function在内部已经把要return 的数据算完了
Function.prototype.myBind = function (context = window, ...args1) {
    // 存储当前函数
    const fn = this

    // 返回新的函数,新的function在执行的时候可能会传入参数
    return function(...args2) {
        const allArgs = args1.concat(args2)

        // 判断是不是new调用的
        if (this instanceof(fn)){
            return new fn(allArgs)
        }
        // 不是new调用,且不使用apply
        // 借助中间值
        context.fn=fn
        const result = context.fn(allArgs)
        delete context.fn
        return result

        // 如果使用apply
        return fn.apply(context,allArgs)
    }
}

// apply函数,直接调用函数并返回结果
Function.prototype.myApply = function(context=window,args){
    console.log(context,"---------------传进来的实例")
    console.log(this,"---------------this")
    console.log(...args,"---------------args")

    // 借助中间变量
    context.Symbol(fn)=this
    const result = Array.isArray(args)?context.fn(...args):context.fn()
    delete context.fn

    return result
}

function a(name){
    console.log(name,...arguments,"---------------------------a的log")
}

const obj={
    a:'李四'
}
const b=a.myApply(obj,[1,2,3])


// call函数
Function.prototype.myCall = function(context = window, ...args) {
  if (this === Function.prototype) {
    return undefined; // 防止Function.prototype.myCall()直接调用
  }
  context = context || globalThis; // 或者使用window/global等全局对象
  const fnKey = Symbol(); // 创建一个唯一的属性以避免覆盖同名属性
  context[fnKey] = this; // 将当前函数赋值给context的一个属性
  const result = context[fnKey](...args); // 以context为上下文调用函数
  delete context[fnKey]; // 删除临时属性
  return result; // 返回函数调用的结果
};

// 示例使用
function greet(name, greeting) {
  console.log(`${greeting},${name}!`);
}

greet.myCall(null, 'Alice', 'Hello'); // 输出: Hello, Alice!