【问题标题】:Partial application of JavaScript methods: how to retain th meaning of “this”JavaScript方法的部分应用:如何保留“this”的含义
【发布时间】:2013-06-27 21:46:38
【问题描述】:

在 JavaScript 中,为函数定义部分应用方法非常容易:

Function.prototype.partial = function partial() {
    var fn = this
    var args = Array.prototype.slice.call(arguments)

    return function() {
        var newArgs = Array.prototype.slice.call(arguments)
        return fn.apply(this, args.concat(newArgs))
    }
}

它适用于函数:

var biggerThanFive = Math.max.partial(5)
assert biggerThanFive(x) === Math.max(5, x)

但结果函数的“this”与原始函数不同:

function Test() {
    this.name = 'test'
}

Test.prototype.a = function(b) {
    return [this.name, b]
}

var test = new Test()

test.a('x') // ['test','x']

var b = test.a.partial('y')
b() // [undefined,'y']

这可以通过手动将生成的函数绑定回其原始绑定对象来解决:

var c = test.a.partial('z').bind(test)
c() //['test','z']

如何在Function.prototype.partial 定义中执行此操作? test.a 客观地知道它的“this”是“测试”,那么我该如何获取这些知识呢?


我从 Esailija 那里学到了什么:

JavaScript 不会在调用时以外的任何时候确定函数内部的“this”是什么。 var d = [].concatvar d = Array.prototype.concat 没有什么不同,调用 d() 将在全局对象上调用它,因为“它的左侧”没有任何内容。

【问题讨论】:

  • 这是this 关键字的问题,而不是您编写的“部分应用程序”方法。调用b()this 的值将是全局范围(即几乎所有浏览器中的window),如果没有名为name 的全局变量,那么您将得到undefined背部。对于浏览器而言,test.ab 的关系并不明显,因为它仅作为具有匿名函数的变量出现在解释器中。
  • 是的,我知道,这就是我想要规避的 :) bind 可以做到,但我想在部分方法中做到这一点。

标签: javascript functional-programming partials


【解决方案1】:

你不能。

不过,您可以使用内置的 .bind 方法来做到这一点,这是您最终会得到并解决的问题:

var b = test.a.bind(test, 'y')
b() 
//["test", "y"]

【讨论】:

  • 这就是我所担心的……虽然我不喜欢从句:我知道一个回合 bind 与 partiaö 的相似之处,但我仍然不明白为什么一个知道它的上下文是什么的方法什么时候不知道'不提供参考。这是 JS 语言设计中的一种严重气味……
  • @flyingsheep 一个函数不知道它的上下文,因为它是一个一流的对象,test.a 只是一个指向该对象的指针。然后,多个变量和属性可以指向同一个函数,而函数不知道它指向什么。即使它知道,选择正确的上下文是什么?
  • 它绑定的那个?所以你是说函数/方法只知道它们的“this”一旦被调用就会指向什么?这种语言很愚蠢!
  • @flyingsheep 显然绑定函数知道this 是什么,您确实可以使用bind 绑定函数。我说的是未绑定的函数。
  • 如果test.aTest.prototype.a = function() {…}; test = new Test()定义的函数,则绑定到test。我想在保留它的绑定的同时对这个函数做点什么。
猜你喜欢
  • 1970-01-01
  • 2019-04-12
  • 1970-01-01
  • 2019-10-04
  • 2022-12-04
  • 1970-01-01
  • 1970-01-01
  • 2012-04-09
  • 2019-02-01
相关资源
最近更新 更多