Question

I am trying to understand how properties of an object relate to methods defined on the object's prototype. The following code prints 'ECMA style 5', while I would expect it to print 'ECMA style 3'.

var util = require('util');

function MyError() { }
util.inherits(MyError, Error);

Object.defineProperty(MyError.prototype, 'toJSON', {
  enumerable: false,
  value: function () {
    return 'ECMA5 style';
  }
});

MyError.prototype.toJSON = function() {
  return 'ECMA3 style';
}

var x = new MyError();
console.log(JSON.stringify(x));

I am reading through an article 1, but I cannot grok why style 3 is not printed since it is defined second in the file. Shouldn't this override the existing method definition?

I am running node v0.10.21

Was it helpful?

Solution

This doesn't have anything to do with whether you're in a Node environment or not. If a specific attribute of the property is not set, they default to false. Data properties have the following attributes (description in parentheses is for when the attribute is false):

  • configurable (cannot be deleted, nor can attributes or type of property be changed)
  • enumerable (cannot be seen in a for-in loop)
  • writable (read-only but can still be deleted)
  • value (the value itself)

Because you haven't specified in your call to Object.defineProperty that writable is true, it cannot be written to and therefore is read-only (reference).

By default, "standard" properties have all of these attributes (apart from value) explicitly set as true (internally), which is why it works normally. A good note by Mike Edwards is that attempting to do what you were doing in ES5 strict mode will throw a TypeError.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top