当前位置: 首页 > news >正文

JavaScript对象属性描述符

属性描述符:JavaScript 对象属性的精细控制

属性描述符是 JavaScript 中用于定义或修改对象属性行为的对象。通过属性描述符,开发者可以精确控制属性的可写性、可枚举性、可配置性,甚至可以通过 getset 方法实现计算属性。

1. 属性描述符的基本结构

使用 Object.getOwnPropertyDescriptor 方法可以获取一个对象属性的描述符。描述符包含以下可选键值:

  • value: 属性的值(仅适用于数据属性)。
  • writable: 布尔值,表示属性是否可写。
  • enumerable: 布尔值,表示属性是否可枚举(例如,是否出现在 for...in 循环中)。
  • configurable: 布尔值,表示属性是否可配置(例如,是否可以删除或修改描述符)。
  • get: 函数,表示属性的 getter(仅适用于访问器属性)。
  • set: 函数,表示属性的 setter(仅适用于访问器属性)。
Object.getOwnPropertyDescriptor(obj, prop);
  • obj: 要查询的对象。
  • prop: 要查询的属性名(字符串或 Symbol)。
2. 定义和获取属性描述符
2.1 定义属性描述符

使用 Object.defineProperty()Object.defineProperties() 方法可以定义或修改对象的属性描述符。

const obj = {};

Object.defineProperty(obj, 'name', {
    value: 'Alice',
    writable: false,      // 不可写
    enumerable: true,    // 可枚举
    configurable: false  // 不可配置
});

console.log(obj.name); // 输出: Alice
obj.name = 'Bob';      // 无效,因为 writable 为 false
console.log(obj.name); // 输出: Alice
2.2 获取属性描述符

使用 Object.getOwnPropertyDescriptor() 方法可以获取对象属性的描述符。

const descriptor = Object.getOwnPropertyDescriptor(obj, 'name');
console.log(descriptor);
// 输出: { value: 'Alice', writable: false, enumerable: true, configurable: false }
3. 使用场景
3.1 防止属性被修改或删除

通过设置 writableconfigurablefalse,可以保护属性不被修改或删除。

Object.defineProperty(obj, 'id', {
    value: 123,
    writable: false,
    configurable: false
});

obj.id = 456; // 无效
delete obj.id; // 无效
3.2 隐藏属性

通过设置 enumerablefalse,可以隐藏属性,使其不出现在 for...in 循环或 Object.keys() 中。

Object.defineProperty(obj, 'secret', {
    value: 'hidden',
    enumerable: false
});

console.log(Object.keys(obj)); // 输出: ['name']
3.3 创建计算属性

使用 getset 方法可以创建计算属性,动态获取或设置值。

const person = {
    firstName: 'John',
    lastName: 'Doe'
};

Object.defineProperty(person, 'fullName', {
    get() {
        return `${this.firstName} ${this.lastName}`;
    },
    set(value) {
        [this.firstName, this.lastName] = value.split(' ');
    }
});

console.log(person.fullName); // 输出: John Doe
person.fullName = 'Jane Smith';
console.log(person.firstName); // 输出: Jane
console.log(person.lastName);  // 输出: Smith
3.4 框架和库中的元编程

许多框架和库(如 Vue.js)使用属性描述符实现数据绑定和响应式系统。

const data = {};

Object.defineProperty(data, 'message', {
    get() {
        return this._message;
    },
    set(value) {
        this._message = value;
        console.log('Message updated:', value);
    }
});

data.message = 'Hello, World!'; // 输出: Message updated: Hello, World!
3.5 在类中使用属性描述符

在类中,属性描述符可以用于限制属性的修改或实现只读属性。

class Goods {
    constructor(goods) {
        // 克隆并冻结原始对象,防止修改
        goods = { ...goods };
        Object.freeze(goods);

        // 定义只读的 data 属性
        Object.defineProperty(this, 'data', {
            get() {
                return goods;
            },
            set(value) {
                throw new Error('data 是只读的');
            },
            configurable: false
        });

        // 定义可写的 name 属性
        let internalGoodsName = '';
        Object.defineProperty(this, 'name', {
            get() {
                return internalGoodsName;
            },
            set(value) {
                internalGoodsName = value;
            }
        });

        // 定义计算属性 totalPrice
        Object.defineProperty(this, 'totalPrice', {
            get() {
                return this.data.price * this.data.num;
            }
        });

        // 密封对象,防止新增属性
        Object.seal(this);
    }
}

// 冻结原型,防止修改
Object.freeze(Goods.prototype);

const goods = new Goods({
    name: '手机',
    price: 3000,
    num: 3
});

console.log(goods.totalPrice); // 输出: 9000
4. 总结

属性描述符为 JavaScript 对象属性提供了精细的控制能力,适用于多种场景,如保护属性不被修改、隐藏属性、创建计算属性等。在现代开发中,属性描述符广泛应用于框架和库中,用于实现数据绑定、响应式系统等高级功能。

相关文章:

  • GreatSQL修改配置文件参数无法生效
  • Android 老项目 jcenter 库失效
  • Plantsimulation中机器人怎么通过阻塞角度设置旋转135°
  • 【深度学习】矩阵的核心问题解析
  • 嵌入式硬件篇---滤波器
  • 国产编辑器EverEdit - 网工利器:使用“插入序列”批量生成维护命令
  • 速通HTML
  • 拓扑排序的核心算法:BFS应用与实践
  • 哈希表_有效的字母异位词
  • 利用python进行数据分析(重点、易忘点)---第九章绘图和可视化
  • Fisher信息矩阵与Hessian矩阵:区别与联系全解析
  • [250224] Yaak 2.0:Git集成、WebSocket支持、OAuth认证等 | Zstandard v1.5.7 发布
  • Openwrt路由器操作系统
  • 蓝桥杯备赛-迷宫-BFS
  • Logic-RL:Unleashing LLM Reasoning with Rule-Based Reinforcement learning
  • 3.1.2移位运算--算术移位
  • 开发 picgo-plugin-huawei 插件,解决华为云社区外链限制问题
  • Visual Studio 安装全攻略
  • 大厂数据仓库数仓建模面试题及参考答案
  • ubuntu windows双系统踩坑
  • 1309家县医院已达到三级医院能力,还有哪些短板要补?
  • 国家统计局督察组:江苏有关地区仍存在干预数据上报等问题
  • 中国戏剧梅花奖终评结果公示,蓝天、朱洁静等15名演员入选
  • 这个死亡率第一的“老年病”,正悄悄逼近年轻人
  • 人民日报头版:紧盯“学查改”,推动作风建设走深走实
  • CBA官方对孙铭徽罚款3万、广厦投资人楼明停赛2场罚款5万