【问题标题】:Emulating javascript `this` behaviour in lua在 lua 中模拟 javascript `this` 行为
【发布时间】:2011-05-24 21:29:53
【问题描述】:

我一直很喜欢在 Javascript 中通过f.call(newThisPtrValue) 设置 this 指针的值的方式。我在 lua 中写了一些东西来做到这一点,这很有效:

_G.call = function(f, self, ...)
    local env = getfenv(f)
    setfenv(f, setmetatable({self = self}, {__index = env}))
    local result = {f(...)}
    setfenv(f, env)
    return unpack(result)
end

有几件事我不确定:

  1. 我预计unpack({...}) 会有性能开销。有没有办法解决这个问题?
  2. 这是否会以任何方式严重破坏函数的环境?
  3. 这真的是个坏主意吗?

【问题讨论】:

    标签: javascript lua


    【解决方案1】:

    Lua 的伪 OOP 的一大优点是它已经非常容易做到这一点:

    local Person = {}
    function Person:create( firstName, lastName )
      local person = { firstName=firstName, lastName=lastName }
      setmetatable(person,{__index=self})
      return person
    end
    function Person:getFullName()
      return self.firstName .. " " .. self.lastName
    end
    local me  = Person:create( "Gavin", "Kistner" )
    local you = Person:create( "Eric", "Someone" )
    print( me:getFullName() )
    --> "Gavin Kistner"
    print( me.getFullName( you ) )
    --> "Eric Someone"
    

    我写了一篇文章讨论这个(除其他外):
    Learning Lua: Pseudo-OOP Syntax and Scope

    编辑:这是一个持续的例子,比如 jQuery 的each

    local Array = {}
    function Array:new(...)
      local a = {...}
      setmetatable(a,{__index=self})
      return a
    end
    function Array:each(callback)
      for i=1,#self do
        callback(self[i],i,self[i])
      end
    end
    function Array:map(callback)
      local result = Array:new()
      for i=1,#self do
        result[i] = callback(self[i],i,self[i])
      end
      return result
    end
    function Array:join(str)
      return table.concat(self,str)
    end
    
    local people = Array:new( me, you )
    
    people:each( function(self,i)
      print(self:getFullName())
    end )
    --> "Gavin Kistner"
    --> "Eric Someone"
    
    print( people:map(Person.getFullName):join(":") )
    --> "Gavin Kistner:Eric Someone"
    

    【讨论】:

    • 确实如此。但是,我打算将它应用到更多的回调函数场景中,使用 self 变量指向正在应用回调的对象。
    • @Eric 您能否在问题中进一步澄清这一点?您所追求的最终功能或模式是什么?类似于 jQuery each 迭代?
    • @Phrogz:这几乎就是我已经拥有的。我只是觉得没有 self 作为函数参数它看起来更整洁。
    • @Eric 查看最终编辑,了解为什么使用内置约定是一个好主意,允许您执行类似于 Ruby 的 Symbol#to_proc 的操作。
    猜你喜欢
    • 2014-02-20
    • 2017-03-28
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    • 2011-08-22
    • 2011-07-09
    • 2020-03-08
    • 1970-01-01
    相关资源
    最近更新 更多