为什么不能在JavaScript中更改对象属性

6
我在这些对象的年龄属性上犯了一个错误,当我尝试重新分配不同的值时,它根本不会改变。
我想让它与Object.create方法一起使用,请问我应该怎么做才能修复这个问题?

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());给出的结果是927,假设出生年份仍为1092,即使我将其更改为1992,预期输出应为27。


3
因为你所使用的属性描述符默认为writable: false - Bergi
请查看Object.defineProperties() - Jeto
2个回答

8

默认情况下,使用Object.create分配的属性是不可写的。在JavaScript中尝试写入不可写属性是一个静默错误 - 这是使用严格模式的众多原因之一。

以下是您的代码,但是在严格模式下:

'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

注意它现在会触发一个错误,并告诉你到底哪里出了问题。

要解决这个问题,只需将属性设置为可写。

'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


2
"silent error". 又一个伟大的JS设计。缓慢鼓掌 - Eric Duminil

2
Object.create的第二个参数使用属性描述符,而当您未指定其时,writable属性默认为false

我建议完全放弃第二个参数,并改用Object.assign在新对象上创建属性:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接