95

I was trying out this really simple example from the awesome "Professional JavaScript for Web Developers" book by Nicholas Zakas but I can't figure what I am doing wrong here. Must be something really simple that I missed but I'm stuck.

Here is the code:

'use strict';

var book = {};

Object.defineProperties(book, {
    originYear: {
        value: 2004,
        writable: false
    },

    _year: {
        value: 2004
    },

    edition: {
        value: 1
    },

    year : {
        get: function() {
            return this._year;
        },

        set: function(newValue) {
            if(newValue > this.originYear) {
                this._year = newValue;
                this.edition += newValue - this.originYear;
            }
        }
    }
});

console.log(book.edition);
book.year = 2006;
console.log(book.edition);

The error I am getting on the Chrome console is:

Uncaught TypeError: Cannot assign to read only property '_year' of #main.js:31 Object.defineProperties.year.setmain.js:39 (anonymous function)

Can someone please explain where I have gone wrong?

Here is the fiddle

4 Answers 4

69

When you use Object.defineProperties, by default writable is set to false, so _year and edition are actually read only properties.

Explicitly set them to writable: true:

_year: {
    value: 2004,
    writable: true
},

edition: {
    value: 1,
    writable: true
},

Check out MDN for this method.

writable
true if and only if the value associated with the property may be changed with an assignment operator.
Defaults to false.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the answer as it lead me to my solution. I had a variable: var thisObject = {name: 'a name', id: 1}; and at some point in the code I was setting thisObject = 1; (i think it was old code or just didn't write it properly...and when I tried to use or set thisObject.name after that I received this error message. Removing the line where I set thisObject to an integer fixed my issue. Hope this helps someone.
7

I had this issue with a Nextjs React setup. If I fired a state setting function it would happen on re-render (firing an onClick function), but not if I loaded the page directly or via refresh. Making a copy of the non editable, or in my case "frozen" object before modifying parameters fixed the problem for me. I was passing an object in Via json and then trying to set some additional properties of it.

book = {...book} 
book.year = 2006;

My own setup looked more like this,

let linkStyle={}
if (appearance.LinkStyle) {
 linkStyle = apperance.LinkStyle
}

linkStyle.color = appearance.primaryColor // Same Error here

Resolved by

let linkStyle={}
if (appearance.LinkStyle) {
  linkStyle = {...apperance.LinkStyle}
}

linkStyle.color = appearance.primaryColor

Comments

1

If sometimes a link! will not work. so create a temporary object and take all values from the writable object then change the value and assign it to the writable object. it should perfectly.

var globalObject = {
    name:"a",
    age:20
}
function() {
    let localObject = {
    name:'a',
    age:21
    }
    this.globalObject = localObject;
}

Comments

0

I tried changing year to a different term, and it worked.

public_methods : {
    get: function() {
        return this._year;
    },

    set: function(newValue) {
        if(newValue > this.originYear) {
            this._year = newValue;
            this.edition += newValue - this.originYear;
        }
    }
}

2 Comments

Tried this. But it still throws an error on encountering that assignment to the _year property. Did it execute the assignment without throwing an error for you? Thanks
Leo's answer is correct. Marked down because the answer suggests changing a variable name randomly to fix the bug which would be fixing errors carelessly and probably creating more bugs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.