3

I have the following code, much reduced:

class Animal {
  speak() {}
}

Animal.prototype.speaklouder = function() {};

for (const key in new Animal()) {
  console.log("key", key);
}

This produces, in node 6.11.0,

key speaklouder

Why is that? I thought the class syntax is just sugar? I would expect the function speak to be also listed as an attribute.

Sagar V
  • 12,158
  • 7
  • 41
  • 68
  • Possible duplicate of https://stackoverflow.com/questions/30881632/es6-iterate-over-class-methods - ES6 methods are not enumerable – Daniel Z. Jul 24 '17 at 12:42
  • 1
    @user2311517 I did not find any concrete documentation but per my understanding, methods of class are non-enumerable. You can check **[here](https://jsfiddle.net/9oo5u457/)**. You can also refer to **[Specs](http://www.ecma-international.org/ecma-262/6.0/#sec-functioninitialize)** – Rajesh Jul 24 '17 at 13:31

1 Answers1

2

Class properties are not enumerable, see ecma-262 6.0 14.5.14:

  • 21. For each ClassElement m in order from methods,
  • a. If IsStatic of m is false, then,
  • i. Let status be the result of performing PropertyDefinitionEvaluation for m with arguments proto and false."

http://www.ecma-international.org/ecma-262/6.0/#sec-runtime-semantics-classdefinitionevaluation

Second parameter of PropertyDefinitionEvaluation is enumerable:

http://www.ecma-international.org/ecma-262/6.0/#sec-method-definitions-runtime-semantics-propertydefinitionevaluation

For an example, you can check the _createClass function in the babel output:

function defineProperties(target, props) {
    for (var i = 0; i < props.length; i++) {
        var descriptor = props[i];
        // ...
        descriptor.enumerable = descriptor.enumerable || false;
        // ...
        Object.defineProperty(target, descriptor.key, descriptor);
    }
}

function _createClass(Constructor, protoProps, staticProps) {
    if (protoProps) defineProperties(Constructor.prototype, protoProps);
    // ...
    return Constructor;
}

_createClass(Animal, [{
    key: "speak",
    value: function speak() {}
}]);

https://babeljs.io/repl/#?babili=false&evaluate=true&lineWrap=false&presets=es2015%2Cstage-2&targets=&browsers=&builtIns=false&debug=false&code_lz=MYGwhgzhAECCB2BLAtmE0DeBYAUNaEADgKZgDWAFAJSYC-u9OuCKaAdIQE4D2ALnwE8SbIqTIhuAVwAmxTtAC80AGaT4wXom7xqdANy5cy7vIrBtEXtDLEB0RPGjxiAdzhJUIajWx5o5-AhuEGI2CQBzCgAiGwEogBprWyoDHEYgA

See:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty