0

我想围绕 Javascript 的本机Date对象类型编写一个包装器。对于该日期的每个本地属性,我只想将其代理为我班级拥有的日期。我正在使用咖啡脚本,除了更改日期对象的任何方法外,一切似乎都有效。我想知道我是否错误地设置了绑定。

这是我到目前为止所拥有的。如果您检查它编译成的内容(修改为与 JSLint 一起玩,但行为与我在浏览器中看到的相同),您可以看到它的行为:http: //jsfiddle.net/XRgKM/1/

class CP.MyDate

  @DateProperties: (name for name in Object.getOwnPropertyNames(window.Date.prototype) when _.isFunction(window.Date.prototype[name]))

  constructor: (@date = new Date()) ->
    # Hack to allow me to use the __bind function like the rest of the
    # 'coffeescript native' class functions:
    bnd = `__bind`
    for name in MyDate.DateProperties
      bnd(@[name], @)

    # Validate parameter:
    if not @date instanceof Date
      throw new Error("date must be a native date")

    # Copy date locally:
    @date = new Date(@date)

  test: () => alert("TEST")

  for name in @DateProperties
    MyDate.prototype[name] = () ->
      returnVal = @date[name].apply(@date, arguments)
      if returnVal isnt @date and returnVal instanceof Date
        returnVal = new MyDate(returnVal)
      return returnVal
4

1 回答 1

1

您在循环问题中有标准闭包。你认为name这里的功能会是什么?

for name in @DateProperties
  MyDate.prototype[name] = () ->
    returnVal = @date[name].apply(@date, arguments)
    if returnVal isnt @date and returnVal instanceof Date
      returnVal = new MyDate(returnVal)
    return returnVal

在函数内部,name将是的最后一个值,@DateProperties这与您想要的完全不同。您需要获取name函数的当前值而不是name引用。由于这是很常见的事情,CoffeeScript 有一个do关键字来帮助:

当使用 JavaScript 循环生成函数时,通常会插入一个闭包包装器,以确保循环变量是封闭的,并且所有生成的函数不只是共享最终值。CoffeeScript 提供了do关键字,它立即调用传递的函数,转发任何参数。

你想这样做:

for name in @DateProperties
  do (name) ->
    # Carry on as before...

演示:http: //jsfiddle.net/ambiguous/8gc7b/

另请注意,jsfiddle 支持 CoffeeScript,请查看侧边栏中的面板下。

而且你不需要DateProperties像那样显示,你可以隐藏它:

class CP.MyDate

  DateProperties = (name for name in Object.getOwnPropertyNames(window.Date.prototype) when _.isFunction(window.Date.prototype[name]))

DateProperties在您的CP.MyDate班级内参考。

于 2012-10-06T00:06:24.600 回答