假设你的压痕真的是这样的:
class CommandParser
obj:
message: null
indicator: 'warning'
stackTrace: null
result: null
isException: false
constructor: (@command, @params, @result) ->
@obj.result = result
那么你没有得到一个TypeError为@obj
正在undefined
,因为没有result
变量,您将收到ReferenceError。
当你说:
m: (@i) -> ...
任何方法然后在参数列表中的@i
该参数值自动给你的对象上@i
实例变量,但不会有一个i
局部变量。所以你constructor
:
constructor: (@command, @params, @result) ->
当你调用它,但没有result
局部变量仍遥不可及自动设置@command
,@params
和@result
实例变量。如果你想看看result
值,那么你就看着@result
:
constructor: (@command, @params, @result) ->
@obj.result = @result
# ------------^
,或者你会离开的@
关闭参数列表:
constructor: (@command, @params, result) ->
@obj.result = result
这就是明显的bug照顾的,隐藏的错误接下来。当你定义在类级别的东西:
class C
p: { a: 11 }
然后p
是C
的原型所以它是由C
所有实例共享的一部分。在你的情况下,只有一个@obj
将通过CommandParser
所有实例共享的对象,所以如果你说:
c1 = new CommandParser('c1', 'p1', 'r1')
c2 = new CommandParser('c2', 'p2', 'r2')
那么这两个c1.obj.result
和c2.obj.result
因为他们使用完全相同的@obj
参考这两个会'r2'
。
演示:https://jsfiddle.net/ambiguous/kffswpxm/
类级别定义可变值几乎总是错误的,在构造函数中定义它们,使每个实例都有自己:
class CommandParser
constructor: (@command, @params, @result) ->
@obj =
message: null
indicator: 'warning'
stackTrace: null
result: @result
isException: false
演示:https://jsfiddle.net/ambiguous/k3kmg1cc/
如果你想在类级别文档的目的来定义他们,那么你要克隆它在构造函数:
class CommandParser
obj:
message: null
indicator: 'warning'
stackTrace: null
result: null
isException: false
constructor: (@command, @params, @result) ->
@obj = _(@obj).cloneDeep()
@obj.result = @result
演示:https://jsfiddle.net/ambiguous/r69vood7/
这个例子使用cloneDeep
from Lodash,有几乎每个实用带JavaScript库都有类似的克隆工具。