Reputation: 473
I've recently restructured my three.js project and I started to encounter a problem where every object seems to be rendered with the exact same geometry and material. I tracked the problem to this constructor in the debugger:
function Geometry() {
Object.defineProperty( this, 'id', { value: GeometryIdCount() } );
this.uuid = exports.Math.generateUUID();
...
Chrome shows no properties on the this
object after the Object.defineProperty
, and id
comes back as undefined
when things try to use it later. However, when I debug older projects I've made using three.js, the id
is defined on this
in the debugger after the call.
What could cause Object.defineProperty
to do nothing? The most likely culprit is that I've switched from using node.js require
calls from Javascript to include three to ES6 import
calls from Typescript with a TS compiler, but it's not clear to me why that would have this effect on this constructor.
Upvotes: 0
Views: 473
Reputation: 1178
Just saying that "id
comes back as undefined" doesn't necessarily mean that Object.defineProperty
did nothing, although I do understand that you looked at the properties of this
directly after the Object.defineProperty
call, and I can't explain that. If GeometryIdCount()
returns undefined, then that would explain why the value is undefined
later. Have you verified that the property itself is undefined, rather than the property value, after the constructor completes?
It may be like using the word "utilize" instead of "use", or maybe Typescript, ES6 or three.js require it, but why don't you instead write:
this.id = GeometryIdCount();
This will still assign unknown to this.id
if the function returns undefined, however.
Update: Your question got me to research exactly what Object.defineProperty does, and it was surprising and very informative. When I worked with WebGL, I didn't use three.js, so I incorrectly assumed that Geometry was a function that you wrote.
When you call Object.defineProperty in the way that you describe, (setting the 3rd argument to an Object with only the "value" property) it sets the writable, configurable and enumerable properties, which all Object properties have, to false. The statement this.id = GeometryIdCount()
, on the other hand, will set those 3 properties to true. The author of three.js apparently wanted to assign a unique key to each Geometry object and make it so the user can't change its value. I didn't look for other reasons.
I recommend that you make a copy of your project and whittle out anything that you want to keep secret, (if you want to post it here) and get rid of as much distracting code as you can, to make it easier to determine what is causing the problem. You know, stop removing code when you can no longer reproduce this bad behavior where the id property is not created or it is undefined. I made a small program and tried to guess how to repro the problem, doing bad things like Geometry.prototype.id = undefined
before calling var g = Geometry(...)
, (without the new keyword) but was unable to reproduce the problem. I didn't go so far as to try to override the behavior of GeometryIdCount
, or prevent the creation of the id
property. That seems like intentional sabotage, and I doubt you suspect that in your case.
Upvotes: 1