【问题标题】:Do ruby Proc/lambda have a 'this' function like javascript closure ?ruby Proc/lambda 有像 javascript 闭包这样的“this”函数吗?
【发布时间】:2012-06-20 07:38:48
【问题描述】:

在 javascript 闭包中,'this' 引用实际调用函数的对象。

ruby Proc/lambda 也有 'this' 功能吗?

如果不是,如果我想要 ruby​​ 中的“this”,我应该怎么做?除了通过参数将当前对象传递给 Proc/lambda。

【问题讨论】:

    标签: ruby lambda proc


    【解决方案1】:

    this 通常不是函数或闭包概念的一部分。函数只是你可以用参数调用的东西; “当前对象”与它有什么关系? this 存在于 JavaScript 中的所有函数中,来自于该语言中方法工作的特殊方式。

    在 JavaScript 中,所有函数都有this 的概念,因为在 JavaScript 中,方法和函数之间没有分隔。任何函数都可能被用作方法;您可以简单地通过将函数分配为对象的属性来向对象添加方法。此外,在 JavaScript 中,函数没有针对当前对象的显式参数(与 Python 不同);那么方法如何访问其对象呢?当您运行方法调用表达式时,它会将您调用它的对象作为隐式this 参数传递给函数。但是,如果您使用该属性获取该函数并像任何其他函数一样手动调用它,this 将是全局对象(或在严格模式下,未定义)。

    换句话说,在 JavaScript 中,当你通过属性从对象中获取方法时,它是一个“未绑定方法”——它不知道它来自哪个对象;相反,当您将函数作为按属性的方法放入对象时,该函数不需要知道要从哪个对象开始-该对象将在调用它时通过方法调用语法神奇地传递给它。您还可以通过在函数上使用.call().apply() 方法人为地将this 参数提供给函数(obj.foo(x) 等效于obj.foo.call(obj, x))。

    在 Ruby 中,方法和匿名函数完全分离。使用lambdaprocProc.new 等创建的匿名函数是数据,可以存储在变量中。它们的调用语法(call[])与方法不同。方法是使用def 定义的,您不能通过简单地写它的名称(将调用它)将其作为数据获取。可以使用对象上的method 方法从对象中获取方法,给出方法名称,然后返回Method 对象。您可以使用 Method 对象,例如 Proc 对象,例如你可以打电话给call;您甚至可以使用to_proc 将其转换为Proc。与 JavaScript 不同,绑定方法(Method 类)和未绑定方法(UnboundMethod 类)之间存在区别。当你从一个对象中得到一个方法时,它就被绑定了——它知道它的对象;如果需要,您可以取消绑定并将其绑定到另一个对象。

    此外,在 Ruby 中,您不能只获取 Proc 并将其附加到对象并使其成为方法,因为方法具有在 Proc 中无效的语法(例如 @some_var)。要将方法添加到对象,您可以使用 instance_exec 并将方法定义 (def) 放入块中。

    简而言之,闭包中的this 概念处理了JavaScript 中在大多数语言中都没有的独特情况。尤其是 Ruby 中不会出现这个问题,因为 Ruby 的对象的方法是绑定方法,而且不能随意插入闭包作为方法。

    附:其他人评论了捕获self,从其中定义闭包到闭包中。然而,这根本不是 JavaScript 中的 this 的意义所在。

    【讨论】:

      【解决方案2】:

      如果您在 Ruby 对象中初始化 lambda 或 proc,则可以使用 self。例如:

      class Example
      
        def name
          "Example"
        end
      
        def test
          lambda{ puts self.name}.call
        end
      
      end
      
      example = Example.new
      example.test # "Example"
      

      有关 Ruby 的 self 的更详细说明,请参阅:http://sidtalk.wordpress.com/2008/10/06/what-exactly-is-ruby-self/

      【讨论】:

      • 那里甚至不需要self
      • @AndrewMarshall 正确。我包括它是因为问题是 Ruby 是否引用了实际进行调用的对象。 self 就是那个参考。
      • 我认为这里的“自我”指的是定义它的对象,而不是真正发出调用的对象。
      猜你喜欢
      • 2013-07-10
      • 2016-06-10
      • 2021-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多