未捕获的类型错误: 无法分配给只读属性

Uncaught TypeError: Cannot assign to read only property

本文关键字:分配 只读属性 错误 类型      更新时间:2023-09-26

我正在尝试Nicholas Zakas的令人敬畏的"Web 开发人员的专业JavaScript"一书中的这个非常简单的例子,但我无法弄清楚我在这里做错了什么。一定是我错过了一些非常简单的事情,但我被卡住了。

这是代码:

'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);

我在Chrome控制台上遇到的错误是:

未捕获类型错误: 无法分配给只读属性"_year"#main.js:31 Object.defineProperties.year.setmain.js:39 (匿名函数)

有人可以解释一下我哪里出错了吗?

这是小提琴

当你使用 Object.defineProperties 时,默认情况下writable设置为 false ,所以_yearedition实际上是只读属性。

将它们显式设置为writable: true

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

查看 MDN 了解此方法


writable true当且仅当可以使用赋值运算符更改与属性关联的值时。
默认为 false

如果有时链接!将不起作用。因此,创建一个临时对象并从可写对象中获取所有值,然后更改该值并将其分配给可写对象。它应该完美。

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

我在Nextjs React设置中遇到了这个问题。如果我触发了一个状态设置函数,它会在重新渲染(触发 onClick 函数)时发生,但如果我直接或通过刷新加载页面,则不会。在修改参数之前复制不可编辑的对象,或者在我的情况下"冻结"对象为我解决了问题。我在 Via json 中传递一个对象,然后尝试设置它的一些其他属性。

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

我自己的设置看起来更像这样,

let linkStyle={}
if (appearance.LinkStyle) {
 linkStyle = apperance.LinkStyle
}
linkStyle.color = appearance.primaryColor // Same Error here

解决者

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

我尝试将year更改为其他术语,它奏效了。

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