【问题标题】:Object.defineProperty does nothing in constructorObject.defineProperty 在构造函数中什么都不做
【发布时间】:2016-10-09 12:36:54
【问题描述】:

我最近重组了我的 three.js 项目,我开始遇到一个问题,即每个对象似乎都使用完全相同的几何图形和材质进行渲染。我在调试器中跟踪到这个构造函数的问题:

function Geometry() {
    Object.defineProperty( this, 'id', { value: GeometryIdCount() } );
    this.uuid = exports.Math.generateUUID();
    ...

Chrome 在Object.defineProperty 之后在this 对象上没有显示任何属性,当以后尝试使用它时,id 会返回为undefined。但是,当我调试使用three.js 制作的旧项目时,id 是在调用后在调试器中的this 上定义的。

什么会导致Object.defineProperty 什么都不做?最可能的罪魁祸首是我已经从使用来自 JavaScript 的 node.js require 调用切换到包含三个来自 Typescript 的 ES6 import 调用和 TS 编译器,但我不清楚为什么这会对这个构造函数。

【问题讨论】:

    标签: javascript typescript three.js


    【解决方案1】:

    只是说“id 返回未定义”并不一定意味着 Object.defineProperty 什么也没做,尽管我知道您在 Object.defineProperty 调用之后直接查看了 this 的属性,并且我无法解释。如果GeometryIdCount() 返回未定义,那么这将解释为什么稍后该值为undefined。在构造函数完成后,您是否验证了属性本身是未定义的,而不是属性值?

    这可能就像使用单词“utilize”而不是“use”,或者可能Typescript、ES6或three.js需要它,但你为什么不改为写:

    this.id = GeometryIdCount();
    

    但是,如果函数返回 undefined,这仍会将 unknown 分配给 this.id

    更新: 你的问题让我研究了exactly what Object.defineProperty does,这令人惊讶且内容丰富。当我使用 WebGL 时,我没有使用 three.js,所以我错误地认为 Geometry 是您编写的函数。

    当您以您描述的方式调用 Object.defineProperty 时(将第三个参数设置为仅具有“值”属性的对象),它将所有对象属性都具有的可写、可配置和可枚举属性设置为 false .另一方面,声明 this.id = GeometryIdCount() 会将这 3 个属性设置为 true。 three.js 的作者显然想为每个 Geometry 对象分配一个唯一的键,并使其用户无法更改其值。我没有寻找其他原因。

    我建议您复制您的项目并删减任何您想保密的内容(如果您想在此处发布)并尽可能多地删除分散注意力的代码,以便更轻松地确定导致问题的原因。您知道,当您无法再重现未创建或未定义 id 属性的不良行为时,请停止删除代码。我做了一个小程序并试图猜测如何重现这个问题,在调用 var g = Geometry(...) 之前做了像 Geometry.prototype.id = undefined 这样的坏事,(没有 new 关键字)但无法重现这个问题。我并没有尝试覆盖GeometryIdCount 的行为,或者阻止id 属性的创建。这似乎是故意破坏,我怀疑你是否怀疑你的情况。

    【讨论】:

    • 我进入了GeometryIdCount,它似乎返回了一个有效的整数。实际上,我确实将代码更改为您编写的代码,并且可以正常工作。不过,这需要我更改threejs的源代码,所以如果我更新,我将不得不再次这样做,它并不能解开谜团。
    猜你喜欢
    • 2011-01-25
    • 1970-01-01
    • 2018-02-11
    • 2017-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多