首页 > 语言 > JavaScript > 正文

JavaScript的Object.defineProperty详解

2024-05-06 15:32:51
字体:
来源:转载
供稿:网友

=与Object.defineProperty

为JavaScript对象新增或者修改属性,有两种不同方式:直接使用=赋值或者使用Object.defineProperty()定义。如下:

// 示例1var obj = {};// 直接使用=赋值obj.a = 1;// 使用Object.defineProperty定义Object.defineProperty(obj, "b",{ value: 2});console.log(obj) // 打印"{a: 1, b: 2}"

这样看两者似乎没有区别,对吧?但是,如果使用Object.getOwnPropertyDescriptor()查看obj.a与obj.b的属性的描述描述符(property descriptor)时,会发现=与Object.defineProperty并不一样:

// 示例2var obj = {};obj.a = 1;Object.defineProperty(obj, "b",{ value: 2});console.log(Object.getOwnPropertyDescriptor(obj, "a")); // 打印"{value: 1, writable: true, enumerable: true, configurable: true}"console.log(Object.getOwnPropertyDescriptor(obj, "b")); // 打印"{value: 2, writable: false, enumerable: false, configurable: false}"

可知,使用=赋值时,属性的属性描述符value是可以修改的,而writable、enumerable和configurable都为true。

而使用Object.defineProperty()定义的属性的属性描述符writable、enumerable和configurable默认值为false,但是都可以修改。对于writable、enumerable和configurable的含义,从名字就不难猜中,后文也会详细介绍。

使用=赋值,等价于使用Object.defineProperty()定义时,同时将writable、enumerable和configurable设为true。代码示例3和4是等价的:

// 示例3var obj = {};obj.name = "Fundebug";console.log(Object.getOwnPropertyDescriptor(obj, "name")); // 打印{value: "Fundebug", writable: true, enumerable: true, configurable: true}
// 示例4var obj = {};Object.defineProperty(obj, "name",{ value: "Fundebug", writable: true, enumerable: true, configurable: true});console.log(Object.getOwnPropertyDescriptor(obj, "name")); // 打印{value: "Fundebug", writable: true, enumerable: true, configurable: true}

Object.defineProperty()

使用Object.defineProperty()定义时若只定义value,则writable、enumerable和configurable默认值为false。代码示例5和6是等价的:

// 示例5var obj = {};Object.defineProperty(obj, "name",{ value: "Fundebug"});console.log(Object.getOwnPropertyDescriptor(obj, "name")); // 打印{value: "Fundebug", writable: false, enumerable: false, configurable: false}
// 示例6var obj = {};Object.defineProperty(obj, "name",{ value: "Fundebug", writable: false, enumerable: false, configurable: false});console.log(Object.getOwnPropertyDescriptor(obj, "name")); // 打印{value: "Fundebug", writable: false, enumerable: false, configurable: false}

由于writable、enumerable和configurable都是false,导致obj.name属性不能赋值、不能遍历而且不能删除:

// 示例7var obj = {};Object.defineProperty(obj, "name",{ value: "Fundebug"});// writable为false,无法赋值obj.name = "云麒";console.log(obj.name); // 打印"Fundebug"// enumerable为false,无法遍历console.log(Object.keys(obj)); // 打印"[]"// configurable为false,无法删除delete obj.name;console.log(obj.name); // 打印"Fundebug"            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选