首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JavaScript 對象屬性特性:defineProperties 設置 writable:true 才能修改內部值

     編輯:程式設計綜合問答

現象代碼

var book = {};
Object.defineProperties(book, {
    _year: { value: 2004 },           // 默認 writable: false
    edition: { value: 1 },            // 默認 writable: false
    year: {
        get: function() { return this._year; },
        set: function(newValue) {
            if (newValue > 2004) {
                this._year = newValue; // 嚴格模式下拋 TypeError
                this.edition += newValue - 2004;
            }
        }
    }
});
book.year = 2015;
console.log(book.year);   // 2004 (未修改)
console.log(book.edition); // 1   (未修改)

根本原因

Object.defineProperties 定義的數據屬性默認特性:

  • writable: false —— 不能賦值修改
  • enumerable: false —— for...in 不枚舉
  • configurable: false —— 不能刪除/重新定義

Setter 內部 this._year = newValue 試圖寫入 writable: false 的屬性,嚴格模式下拋異常,非嚴格模式靜默失敗。

修正代碼

Object.defineProperties(book, {
    _year: { value: 2004, writable: true },   // 關鍵:允許寫入
    edition: { value: 1, writable: true },    // 關鍵:允許寫入
    year: {
        get: function() { return this._year; },
        set: function(newValue) {
            if (newValue > 2004) {
                this._year = newValue;
                this.edition += newValue - 2004;
            }
        }
    }
});

最佳實踐:使用 Object.defineProperty 簡寫

Object.defineProperty(book, '_year', { value: 2004, writable: true });
Object.defineProperty(book, 'edition', { value: 1, writable: true });

進階:ES6 Class 私有字段(現代替代方案)

class Book {
    #_year = 2004;      // 真正私有,外部不可訪問
    #edition = 1;
    get year() { return this.#_year; }
    set year(v) {
        if (v > 2004) {
            this.#_year = v;
            this.#edition += v - 2004;
        }
    }
}

總結

  • 定義可寫數據屬性必須顯式 writable: true。
  • 訪問器屬性(get/set)不受 writable 影響,但內部操作的數據屬性需可寫。
  • 新項目優先用 class + #private,語義清晰、原生私有、無需 defineProperty 样板代碼。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved