有没有什么方法可以解决在某些范围内冻结对象而不是其他范围内的对象?

时间:2016-10-07 23:36:01

标签: javascript typescript interface

我有一个界面:

interface Model {
  pre: Vertices,
  post: Vertices,
  m: Matrix,
  viewport: Vector,
  halfViewport: Vector,
  mouse: MouseState,
  selection: boolean
}

我的应用程序中的状态对象是Model的一个实例,选择属性被初始化为false。请注意,没有只读装饰器:

const state: Model = {
  ...
  selection : false
}

出于性能目的,模型值会更新到位,因为大多数属性都是引用类型。因此代码中有一些地方会更新属性,有些位于调用堆栈中。

现在,我注意到在顶级作用域中的函数中,更新Model对象的选择属性对我来说完全合法:

function draw(state){   state.selection =!state.selection   ... }

我实际上并没有在我的代码中进行此调用,但是注意的关键我可以修改该选择属性,因为在堆栈中,在React组件事件处理程序中,我将尝试为selection分配一个值:

function app (S: Model) : DOMElement<HTMLAttributes, Element> {
  const props = {
    ...
    onMouseDown: function (e: MouseEvent) : void {
      ...
      S.selection = false
    }
  }
  return React.DOM.div(props)
}

但是该分配会引发以下错误:

Uncaught TypeError: Cannot assign to read only property 'selection' of object '#<Object>'

起初我做了双重拍摄并检查了我在readonly声明中没有写Model,但我没有。当我查看Chrome调试器时,我发现S处的对象已冻结(例如,tsc调用`Object.freeze&#39; on things。我相信这与TS中的多余属性检查有关,其中接口实例在分配给变量或参数时会被检查,但是在这周围有什么呢?我可以在一个范围内实现突变而不是另一个范围,这似乎超级不一致

1 个答案:

答案 0 :(得分:3)

  

我发现S处的对象被冻结(如,tsc在事物上调用`Object.freeze'。我相信这与TS中的多余属性检查有关,其中接口实例在分配给变量时会被检查参数,但是还有吗?

没有类似的事情发生。 TypeScript不会发出调用Object.freeze的代码。当然,您可以自己阅读发出的JavaScript。除了删除类型注释并将ES6 +构造转换为等效的ES5代码之外,TypeScript从不做任何事情,其中​​任何一个都不包括在随机内容上调用freeze

其他东西冻结了这个物体。我怀疑您可能正在尝试在React state对象上设置属性,而不是正确调用setState,但如果没有完整的示例,很难说。