【问题标题】:Can setters modify non-writable/non-configurable properties?设置器可以修改不可写/不可配置的属性吗?
【发布时间】:2015-11-11 20:39:47
【问题描述】:

我一直在阅读有关属性属性(可配置、可写、可枚举)的内容,并且正在寻找有关 setter 如何与不可写/不可配置属性交互的一些说明。

具体来说,如果使用Object.defineProperty() 定义属性,它将默认为configurable: falsewritable: false。在这种情况下,同一个对象中的 setter 函数是否仍然能够修改属性的值?

这是我正在查看的示例:

var book = {};

Object.defineProperties(book, {
    _year: {
        value: 2004
    },
    edition: {
        value: 1
    },
    year: {
        get: function(){
            return this._year;
        },
        set: function(newValue){
            if (newValue > 2004) {
                this._year = newValue;
                this.edition += newValue - 2004;
            }
        }
    }
});

-- 来自“面向 Web 开发人员的专业 JavaScript,第 3 版”。 (尼古拉斯·C·扎卡斯)

因此,book.year 的 setter 部分旨在更新 book._year 的值。

但是由于book._year 是使用Object.defineProperty 定义的,并且没有明确设置为可写或可配置,所以不应该是不可修改的吗?或者同一对象中的函数(即book.year)是否以某种方式排除在这些限制之外?

还值得注意的是,当我在浏览器中运行这段代码时,它给了我一些有趣的结果......即: book.year = 2005book.yearbook._year 没有任何作用,并且 book.year(2005) 导致 TypeError: book.year is not a function

【问题讨论】:

    标签: javascript oop getter-setter


    【解决方案1】:

    对于自属性,没有关于 writable true/false 的排除。如果您有非 writable 属性,则无法从您想要更改的位置进行更改。当您可以将描述符更改为可写时,可配置值除外。

    关于 TypeError 的另一个问题:
    使用 `defineProperty` 的属性定义中的 setter 函数是一个隐藏方法,在您分配属性时调用。这不是外部的实际功能。

    【讨论】:

    • 您能否澄清一下,或者将我发送到您的消息来源以获得您答案的“没有排除”部分?我仍然不清楚为什么示例中的设置器(据说)能够更改不可写的_year,或者为什么我在尝试运行代码时会收到 TypeError。
    • 我的意思是你可以改变一个不可写的属性,只有将writable: false改为writable: true,如果它是可配置的。没有其他方法可以更改这种属性。我如前所述制作了一个屏幕截图以显示,当 setter 以 3005 的值执行时,this._year 正在分配,但没有写入,(this._year = 3005 不起作用,因为它是不可写的),所以你不能向该属性写入任何内容。关于您的错误:set、get 函数是隐藏函数,它们在您分配值时执行,例如 `book.year = 3005'
    • 然后 setter 函数正在调用。 'year' 是一个属性,而不是一个方法,所以你会得到一个错误
    • 所以,你是说这个例子有问题——给定的代码实际上并没有提供改变this._year的方法。对吗?
    猜你喜欢
    • 2017-04-25
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-22
    • 2015-07-03
    相关资源
    最近更新 更多