SamSam
SamSam

Reputation: 91

why can't I change object property in JavaScript

I made a mistake with the age property on these objects and when I try to reassign different values later, it won't change it at all.

I want this to work with the Object.create Method. What should I do to fix this?

var personProto = {
  calculateAge: function() {
    console.log(2019 - this.yearOfBirth)
  },
  fullName: function() {
    console.log(this.name + ' ' + this.lastName)
  }
}

var sam = Object.create(personProto, {
  name: { value: "samuel" },
  yearOfBirth: { value: 1092 },
  lastName: { value: "max" },
  job: { value: "developer" }
});

sam.yearOfBirth = 1992;

sam.calculateAge(); // 927

console.log(sam.calculateAge()); is giving me 927 assuming yearsOfBirth is still 1092 even if I changed it to 1992 and the output was supposed to be 27.

Upvotes: 6

Views: 8561

Answers (2)

Bergi
Bergi

Reputation: 665485

The second argument to Object.create uses property descriptors, and the writable attribute defaults to false when you don't specify it.

I would recommend to drop the second argument entirely, and instead use Object.assign to create the properties on the new object:

var sam = Object.assign(Object.create(personProto), {
    name: 'samuel',
    yearOfBirth: 1092,
    lastName: 'max',
    job: 'developer',
});

Upvotes: 2

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324800

By default, properties assigned using Object.create are not writable. Attempting to write to a non-writable property is a silent error in JavaScript - one of many reasons to use Strict Mode.

Here is your code again, but in Strict Mode:

'use strict';

var personProto = {

        calculateAge:function(){
            console.log(2019 -this.yearOfBirth)
        },
        fullName:function(){
            console.log(this.name + ' ' + this.lastName)
        }
    }

    var sam = Object.create(personProto, {
        name:{value:'samuel'}, 
        yearOfBirth:{value:1092}, 
        lastName:{value:'max'},
        job:{value:'developer'}
    });

    sam.yearOfBirth = 1992;

    console.log(sam.calculateAge());
    927

Notice that it now fires an error and tells you exactly what's wrong.

To fix this, just make the properties writable.

'use strict';

var personProto = {

        calculateAge:function(){
            console.log(2019 -this.yearOfBirth)
        },
        fullName:function(){
            console.log(this.name + ' ' + this.lastName)
        }
    }

    var sam = Object.create(personProto, {
        name:{value:'samuel',writable:true}, 
        yearOfBirth:{value:1092,writable:true}, 
        lastName:{value:'max',writable:true},
        job:{value:'developer',writable:true}
    });

    sam.yearOfBirth = 1992;

    console.log(sam.calculateAge());
    927

Upvotes: 8

Related Questions