Предполагая, что ваш отступы действительно выглядит следующим образом:
class CommandParser
obj:
message: null
indicator: 'warning'
stackTrace: null
result: null
isException: false
constructor: (@command, @params, @result) ->
@obj.result = result
тогда вы не получаете TypeError для @obj
undefined
, вы получаете 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
«s поэтому она совместно всеми экземплярами C
. В вашем случае, есть только один @obj
объект, который будет использоваться всеми экземплярами CommandParser
, так что если вы скажете:
c1 = new CommandParser('c1', 'p1', 'r1')
c2 = new CommandParser('c2', 'p2', 'r2')
тогда как c1.obj.result
и c2.obj.result
будут 'r2'
, потому что они оба используют точно такую же @obj
ссылки ,
Демо: 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 утилиты.