#javascript #typescript #three.js
#javascript #typescript #three.js
Вопрос:
Я недавно реструктурировал свой three.js мы с проектом начали сталкиваться с проблемой, когда кажется, что каждый объект визуализируется с одинаковой геометрией и материалом. Я отследил проблему до этого конструктора в отладчике:
function Geometry() {
Object.defineProperty( this, 'id', { value: GeometryIdCount() } );
this.uuid = exports.Math.generateUUID();
...
Chrome не показывает никаких свойств для this
объекта после Object.defineProperty
, и id
возвращается, undefined
когда что-то пытается использовать его позже. Однако, когда я отлаживаю старые проекты, которые я создал с помощью three.js , id
определяется this
в отладчике после вызова.
Что может привести Object.defineProperty
к тому, что ничего не делать? Наиболее вероятным виновником является то, что я перешел от использования node.js require
вызовы из Javascript включают import
в себя вызовы от трех до ES6 из Typescript с компилятором TS, но мне непонятно, почему это так повлияет на этот конструктор.
Ответ №1:
Просто сказать, что « id
возвращается как неопределенный», не обязательно означает, что Object.defineProperty
это ничего не сделало, хотя я понимаю, что вы смотрели на свойства this
непосредственно после Object.defineProperty
вызова, и я не могу это объяснить. Если GeometryIdCount()
возвращает undefined , то это объясняет, почему значение undefined
позже. Вы проверили, что само свойство не определено, а не значение свойства, после завершения конструктора?
Это может быть похоже на использование слова «использовать» вместо «использовать», или, может быть, Typescript, ES6 или three.js требуйте этого, но почему бы вам вместо этого не написать:
this.id = GeometryIdCount();
Однако это все равно будет присваивать unknown this.id
, если функция возвращает undefined .
Обновление: ваш вопрос заставил меня исследовать, что именно делает Object.defineProperty , и это было удивительно и очень информативно. Когда я работал с WebGL, я не использовал three.js , поэтому я неправильно предположил, что Геометрия — это функция, которую вы написали.
Когда вы вызываете Object.defineProperty так, как вы описываете (устанавливая 3-й аргумент для объекта только со свойством «value»), он устанавливает для записываемых, настраиваемых и перечислимых свойств, которые имеют все свойства объекта, значение false . С this.id = GeometryIdCount()
другой стороны, оператор установит для этих 3 свойств значение true . Автор three.js очевидно, он хотел присвоить уникальный ключ каждому геометрическому объекту и сделать так, чтобы пользователь не мог изменить его значение. Я не искал других причин.
Я рекомендую вам сделать копию вашего проекта и вырезать все, что вы хотите сохранить в секрете (если вы хотите опубликовать это здесь), и избавиться от как можно большего количества отвлекающего кода, чтобы было легче определить, что вызывает проблему. Знаете, прекратите удалять код, когда вы больше не можете воспроизводить это плохое поведение, когда свойство id не создано или оно не определено. Я создал небольшую программу и попытался угадать, как воспроизвести проблему, делая плохие вещи, например Geometry.prototype.id = undefined
, перед вызовом var g = Geometry(...)
(без ключевого слова new), но не смог воспроизвести проблему. Я не заходил так далеко, чтобы пытаться переопределить поведение GeometryIdCount
или предотвратить создание id
свойства. Это похоже на преднамеренный саботаж, и я сомневаюсь, что вы подозреваете это в вашем случае.
Комментарии:
1. Я вошел
GeometryIdCount
, и оказалось, что он возвращает допустимое целое число. Я действительно изменил код на то, что вы написали, и это работает. Однако для этого мне нужно изменить исходный код threejs, поэтому мне придется сделать это снова, если я обновлюсь, и это не решит загадку.