在 Javascript 中使用 apply() 创建我自己的 bind() 函数

Creating my own bind() function using apply() in Javascript

作为练习,我正在尝试使用我刚刚学到的 apply() 和原型继承来创建我自己的 bind() 函数。

这是我的代码:

// Create your own bind() using call() and apply()
const lizard = {
    phrase: 'slither',
    say(phraseToSay) {
        if (!phraseToSay) phraseToSay = this.phrase
        console.log('sss' + phraseToSay)
    },
}

const dragon = {
    phrase: 'sizzle',
}

// My Answer
Function.prototype.mybind = function (object) {
    return () => this.apply(object, arguments)
}

// Solution
Function.prototype.solbind = function (object) {
    let self = this
    return function () {
        self.apply(object, arguments)
    }
}

dragon.say = lizard.say.mybind(dragon)

lizard.say()
dragon.say()
lizard.say('sexy')
dragon.say('sexy')

这是输出:

ssslither
sss[object Object]
ssssexy
sss[object Object]

解决方案是使用self=this。但是在我眼里看起来很丑... 我正在尝试仅使用此功能和箭头功能来完成此操作。但出于某种原因,apply() 传递了第一个参数,即对象本身作为目标函数的实际参数。我不明白为什么会这样,以及如何在不将 this 保存到另一个变量的情况下实现我想要的结果。

当你这样做时:

.... = function (object) { 
  return () => this.apply(object, arguments)
}

你指的是绑定到外部函数表达式的 arguments 对象,而不是你的箭头函数,因为箭头函数没有自己的参数绑定。在这种情况下,该参数对象将包含 dragon,因为您正在使用:

dragon.say = lizard.say.mybind(dragon)

因此,您的参数对象将包含 dragon,当使用 .apply(object, arguments).

时,它将作为参数传递给您的 say 方法

对于提供的解决方案,他们返回一个函数表达式,与箭头函数不同,它有自己的 arguments 绑定,所以在那种情况下,arguments object 是指传递给 solbind().

返回的函数的参数

您可以使用 ES6 rest parameter syntax (...) 而不是引用参数对象来修复您的代码。这样 args 将引用传递给“绑定”函数的参数:

// Create your own bind() using call() and apply()
const lizard = {
    phrase: 'slither',
    say(phraseToSay) {
        if (!phraseToSay) phraseToSay = this.phrase
        console.log('sss' + phraseToSay)
    },
}

const dragon = {
    phrase: 'sizzle',
}

// My Answer
Function.prototype.mybind = function (object) {
    return (...args) => this.apply(object, args)
}

// Solution
Function.prototype.solbind = function (object) {
    let self = this
    return function () {
        self.apply(object, arguments)
    }
}

dragon.say = lizard.say.mybind(dragon)

lizard.say()
dragon.say()
lizard.say('sexy')
dragon.say('sexy')