假設你的壓痕真的是這樣的:
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庫都有類似的克隆工具。