Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting an ES6 class getter to enumerable

I have an ES6 class (transcompiled with babeljs) with a getter property. I understand that these properties are not enumerable by default. However, I do not understand why I am not able to make the property enumerable using Object.defineProperty

// Declare class class Person {   constructor(myName) {     this.name = myName;   }    get greeting() {     return `Hello, I'm ${this.name}`;   } }  // Make enumerable (doesn't work) Object.defineProperty(Person, 'greeting', {enumerable: true});  // Create an instance and get enumerable properties var person = new Person('Billy'); var enumerableProperties = Object.keys(person); // => ['name'] 

Plunker Example

like image 282
lightswitch05 Avatar asked Dec 29 '15 19:12

lightswitch05


People also ask

Are getters enumerable?

Benefit is that getters on plain object are enumerable and configurable by default, you don't have to care about these modifiers every time.

What does it mean for an object property to be enumerable?

Enumerable properties are those properties whose internal enumerable flag is set to true, which is the default for properties created via simple assignment or via a property initializer. Properties defined via Object.

What is an enumerable in JavaScript?

An enumerable property in JavaScript means that a property can be viewed if it is iterated using the for…in loop or Object. keys() method. All the properties which are created by simple assignment or property initializer are enumerable by default.

What is an enumerable object?

An enumerable property is one that can be included in and visited during for..in loops (or a similar iteration of properties, like Object. keys() ). If a property isn't identified as enumerable, the loop will ignore that it's within the object. var obj = { key: 'val' }; console. log('toString' in obj); // true console.


1 Answers

ES6 style getters are defined on the prototype, not on each individual person. To set the greeting property to enumerable you need to change:

// Make enumerable (doesn't work) Object.defineProperty(Person, 'greeting', {enumerable: true}); 

To:

// Make enumerable Object.defineProperty(Person.prototype, 'greeting', {enumerable: true}); 

Object.keys only returns that object's own enumerable properties, so properties on the prototype are not returned. You will find the greeting property in Object.keys( Object.getPrototypeOf( person ) ), or in a for...in loop. Updated Plunker

If instead, you want each individual instance of Person to have its own greeting you can define it in the constructor:

class Person {   constructor(myName) {     this.name = myName;      Object.defineProperty( this, 'greeting', {       enumerable: true,       get: function ( ) { return `Hello, I'm ${this.name}`; }     } );   } } 

Updated Plunker

like image 166
Paul Avatar answered Sep 24 '22 12:09

Paul