我想编写一个围绕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
答案 0 :(得分: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
keyword来帮助:
当使用JavaScript循环生成函数时,通常会插入一个闭包装,以确保循环变量被关闭,并且所有生成的函数不只是共享最终值。 CoffeeScript提供
do
关键字,它立即调用传递的函数,转发任何参数。
你想这样做:
for name in @DateProperties
do (name) ->
# Carry on as before...
演示:http://jsfiddle.net/ambiguous/8gc7b/
另请注意,jsfiddle支持CoffeeScript,请在侧栏中的 Panels 下查看。
你不需要让DateProperties
可见,你可以隐藏它:
class CP.MyDate
DateProperties = (name for name in Object.getOwnPropertyNames(window.Date.prototype) when _.isFunction(window.Date.prototype[name]))
并参考DateProperties
课程中的CP.MyDate
。