js实现defineProperty

使用 Object.defineProperty 实现属性定义
Object.defineProperty 是 JavaScript 中用于直接在对象上定义新属性或修改现有属性的方法。它允许精确控制属性的行为(如可枚举性、可配置性、可写性)以及定义 getter 和 setter。

基本语法
Object.defineProperty(obj, prop, descriptor)
obj:目标对象。prop:要定义或修改的属性名称或 Symbol。descriptor:属性的描述符对象。
描述符的配置选项
属性描述符分为两种类型:
- 数据描述符:包含
value和writable。 - 存取描述符:包含
get和set。
通用选项(两种描述符均可使用)
configurable:默认为false。若为true,则该属性的描述符可被修改,且属性可从对象中删除。enumerable:默认为false。若为true,则该属性会出现在对象的枚举属性中(如for...in循环)。
数据描述符专用选项
value:属性的值,默认为undefined。writable:默认为false。若为true,则属性的值可以被赋值运算符修改。
存取描述符专用选项
get:属性的 getter 函数,默认为undefined。读取属性时调用。set:属性的 setter 函数,默认为undefined。写入属性时调用。
示例代码
定义普通属性
const obj = {};
Object.defineProperty(obj, 'name', {
value: 'John',
writable: true,
enumerable: true,
configurable: true
});
console.log(obj.name); // 输出: John
定义 getter 和 setter
const user = {};
let _age = 0;
Object.defineProperty(user, 'age', {
get() {
return _age;
},
set(newValue) {
if (newValue >= 0) {
_age = newValue;
} else {
console.error('Age cannot be negative');
}
},
enumerable: true,
configurable: true
});
user.age = 25;
console.log(user.age); // 输出: 25
user.age = -1; // 输出: Age cannot be negative
定义不可枚举属性
const obj = {};
Object.defineProperty(obj, 'hiddenProp', {
value: 'secret',
enumerable: false
});
console.log(obj.hiddenProp); // 输出: secret
console.log(Object.keys(obj)); // 输出: [](不可枚举)
注意事项
- 若同时指定
value/writable和get/set,会抛出异常。 - 修改
configurable: false的属性会静默失败(严格模式下报错)。 Object.defineProperty是 Vue 2 响应式系统的核心实现方式之一。
兼容性
- 支持所有现代浏览器和 Node.js。
- 在 IE8 及以下版本中仅能用于 DOM 对象。






