所以我正在查看不属于我的CoffeeScript代码,我试图理解为什么类变量未定义。 CoffeeScript Runtime是1.9
class CommandParser
obj:
message: null
indicator: 'warning'
stackTrace: null
result: null
isException: false
constructor: (@command, @params, @result) ->
@obj.result = result //@obj is undefined
我试图理解为什么@obj未定义
答案 0 :(得分:0)
假设你的缩进看起来像:
class CommandParser
obj:
message: null
indicator: 'warning'
stackTrace: null
result: null
isException: false
constructor: (@command, @params, @result) ->
@obj.result = result
然后你没有得到@obj
为undefined
的TypeError,你得到一个ReferenceError,因为没有result
变量。
当你说:
m: (@i) -> ...
对于任何方法,参数列表中的@i
会自动将该参数值分配给对象上的@i
实例变量,但不会有i
局部变量。那么你的constructor
:
constructor: (@command, @params, @result) ->
在您调用它时会自动设置@command
,@params
和@result
实例变量,但在任何地方都没有result
个局部变量。如果您想查看result
值,请查看@result
:
constructor: (@command, @params, @result) ->
@obj.result = @result
# ------------^
或者你将@
关闭在参数列表中:
constructor: (@command, @params, result) ->
@obj.result = result
这是明显的错误,隐藏的错误接下来。在类级别定义某些内容时:
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
都是'r2'
,因为它们都使用完全相同的@obj
引用。
在类级别定义可变值几乎总是一个错误,在构造函数中定义它们,以便每个实例都有自己的:
class CommandParser
constructor: (@command, @params, @result) ->
@obj =
message: null
indicator: 'warning'
stackTrace: null
result: @result
isException: false
如果您想在类级别定义它们以用于文档目的,那么您需要在构造函数中克隆它:
class CommandParser
obj:
message: null
indicator: 'warning'
stackTrace: null
result: null
isException: false
constructor: (@command, @params, @result) ->
@obj = _(@obj).cloneDeep()
@obj.result = @result
该示例使用cloneDeep
from Lodash,几乎每个实用程序带JavaScript库都有类似的克隆工具。