I'm building a class that is shared between a game engine and an editor. There are some properties and methods I want to be defined in the editor, but not the engine so I wrote the following code
class Asset{
constructor(){
this.prop1 = 1;
}
}
if (window.IS_EDITOR){
Asset.prototype.editorProp = 2;
}
class Room extends Asset{
constructor(){
super();
this.prop2 = 3;
console.log(this)
//expected: {prop1: 1, prop2: 3, editorProp: 2}
//what I get: {pro1: 1, prop2: 3}
}
}
I'm basically just trying to conditionally add another property to the constructor, but I'm confused why the editorProp
isn't showing up when I access this
.
CodePudding user response:
I'm confused why the
editorProp
isn't showing up when I accessthis
.
Because it's on the prototype of your object, just like the .constructor
, and won't be printed by default when you console.log
it. You'll find it if you expand the prototype, or if you console.log(Object.getPrototypeOf(this))
. You still can access it as this.editorProp
with the expected value, as it is inherited.
I'm trying to conditionally add another property to the constructor
If you want to add the property to the instance in the constructor, you should actually do it in the constructor:
class Asset {
constructor() {
this.prop1 = 1;
if (window.IS_EDITOR) {
this.editorProp = 2;
}
}
}
CodePudding user response:
Like pointed out, console.log
is just logging the object, not what's in the prototype chain. So doing console.log(this.editorProp)
will indeed return 2
, as the prototype chain is now been used.
If you want to see the object with the prototype flattened it's pretty easy to do using in
. In the example below I've added a simple function called flat
that does this.
Also worth noting adding methods to a class will make them automatically none enumerable, but if you add a method to the prototype it will be enumerable. So an example below I've also added a function called fn
but using defineProperty
to stop it been enumerable.
window.IS_EDITOR = true;
class Asset{
constructor(){
this.prop1 = 1;
}
}
if (window.IS_EDITOR){
Asset.prototype.editorProp = 2;
//adding a function this will will be
//enumerable, so you might want to use
//defineProperty here.
Object.defineProperty(
Asset.prototype,
'fn',
{value: () => {console.log('fn called')}, enumerable: false});
}
class Room extends Asset{
constructor(){
super();
this.prop2 = 3;
console.log(this.flat());
this.fn();
//expected: {prop1: 1, prop2: 3, editorProp: 2}
//what I get: {pro1: 1, prop2: 3}
}
flat() {
const ret = {};
for (const i in this) ret[i] = this[i];
return ret;
}
}
new Room();