5
votes

I have error when try to define property with accessors. Here is my code

    var person = {};

    Object.defineProperty(person, 'birthYear', {
        value: 1997,
        writable: true,
        enumerable: true,
        configurable: false,
        set: function (value) {
            this.birthYear = value;
        },
        get: function() {
            return 'Birth year - ' + this.birthYear;
        }
    });

    console.log(person.birthYear);

The error text:

Invalid property descriptor. Cannot both specify accessors and a value or writable attribute.

If i can't define set and get methods like this how i can do it?

1
You'd remove the value but you don't want a birthYear getter that retrieves this.birthYear because that would create infinite recursion. You need to store the value elsewhere, like on a different property name or symbol, or in a variable. - user1106925
Is there a reason to define the property on the one object, instead of the prototype - Sᴀᴍ Onᴇᴌᴀ
...and FYI, you can do that object creation/definition in one step using Object.create. - user1106925
@SamOnela Because one does not install arbitrary properties on Object.prototype, and the object in the question doesn't have any other prototypes? - Bergi

1 Answers

21
votes

Look at the error message:

Cannot both specify accessors and a value or writable attribute.

It doesn't make sense to say if a property is writable when you explicitly state what happens when you try to write it.

So remove:

    writable: true,

And you can't give it a value, when the value is calculated dynamically when you read it, so remove:

    value: 1997,

Then you'll get an error about recursion because every time you try to read person.birthYear, your getter function tries to read person.birthYear.

So store the value somewhere else.

var person = { _birthYear: 1997 };

Object.defineProperty(person, 'birthYear', {
    enumerable: true,
    configurable: false,
    set: function (value) {
        this._birthYear = value;
    },
    get: function() {
        return 'Birth year - ' + this._birthYear;
    }
});

console.log(person.birthYear);