福州网站设计软件公司,wordpress百度联盟,纯静态网站做优化有什么影响,注册建筑公司名字大全Object.defineProperty() 完整指南
1. 基本概念
Object.defineProperty() 方法允许精确地添加或修改对象的属性。默认情况下#xff0c;使用此方法添加的属性是不可修改的。
1.1 基本语法
Object.defineProperty(obj, prop, descriptor)参数说明#xff1a;
obj: 要定义…Object.defineProperty() 完整指南
1. 基本概念
Object.defineProperty() 方法允许精确地添加或修改对象的属性。默认情况下使用此方法添加的属性是不可修改的。
1.1 基本语法
Object.defineProperty(obj, prop, descriptor)参数说明
obj: 要定义属性的对象prop: 要定义或修改的属性名descriptor: 属性描述符对象
2. 属性描述符
2.1 数据描述符
const obj {};Object.defineProperty(obj, name, {value: John, // 属性值writable: true, // 是否可写enumerable: true, // 是否可枚举configurable: true // 是否可配置
});2.2 访问器描述符
const obj {_name: John
};Object.defineProperty(obj, name, {get() {return this._name;},set(value) {this._name value;},enumerable: true,configurable: true
});3. 实际应用示例
3.1 数据劫持Vue2响应式原理
function observe(obj) {if (typeof obj ! object || obj null) {return;}Object.keys(obj).forEach(key {defineReactive(obj, key, obj[key]);});
}function defineReactive(obj, key, val) {// 递归处理嵌套对象observe(val);Object.defineProperty(obj, key, {get() {console.log(获取${key}属性);return val;},set(newVal) {if (val newVal) return;console.log(设置${key}属性为${newVal});val newVal;// 触发更新}});
}// 使用示例
const data {name: John,age: 20
};observe(data);
data.name Mike; // 设置name属性为Mike
console.log(data.name); // 获取name属性 Mike3.2 私有属性模拟
function Person(name) {let _name name;Object.defineProperty(this, name, {get() {return _name;},set(value) {if (typeof value ! string) {throw new Error(Name must be a string);}_name value;}});
}const person new Person(John);
console.log(person.name); // John
person.name Mike; // 正常设置
person.name 123; // 抛出错误3.3 计算属性实现
function computed(obj, key, computeFunc) {let value computeFunc();Object.defineProperty(obj, key, {get() {return value;},set() {console.warn(${key} is a computed property, cannot be modified);}});
}const obj {a: 1,b: 2
};computed(obj, sum, () obj.a obj.b);
console.log(obj.sum); // 3
obj.sum 10; // 警告sum is a computed property, cannot be modified4. 注意事项和限制
4.1 不可扩展对象
const obj {};
Object.preventExtensions(obj);// 这将抛出错误
Object.defineProperty(obj, name, {value: John
});4.2 继承属性
const parent {};
Object.defineProperty(parent, name, {value: John,writable: false
});const child Object.create(parent);
// 这将抛出错误
child.name Mike;4.3 属性描述符限制
const obj {};// 不能同时指定 value/writable 和 get/set
Object.defineProperty(obj, name, {value: John,get() {return John;}
}); // 抛出错误5. 性能考虑
5.1 大量属性处理
// 不推荐
const obj {};
for (let i 0; i 1000; i) {Object.defineProperty(obj, prop${i}, {value: i,writable: true});
}// 推荐
const descriptors {};
for (let i 0; i 1000; i) {descriptors[prop${i}] {value: i,writable: true,configurable: true,enumerable: true};
}
Object.defineProperties(obj, descriptors);5.2 访问器性能
// 避免在访问器中进行复杂计算
Object.defineProperty(obj, name, {get() {// 不推荐return complexCalculation();}
});// 推荐缓存计算结果
let cachedValue;
Object.defineProperty(obj, name, {get() {if (cachedValue undefined) {cachedValue complexCalculation();}return cachedValue;}
});6. 最佳实践
描述符默认值
// 记住默认值都是 false
Object.defineProperty(obj, name, {value: John// writable: false// enumerable: false// configurable: false
});使用 TypeScript 类型
interface PropertyDescriptor {configurable?: boolean;enumerable?: boolean;value?: any;writable?: boolean;get?(): any;set?(v: any): void;
}错误处理
function safeDefineProperty(obj, prop, descriptor) {try {Object.defineProperty(obj, prop, descriptor);return true;} catch (error) {console.error(Failed to define property ${prop}:, error);return false;}
}7. 总结
Object.defineProperty() 的关键点 使用场景 数据劫持私有属性模拟计算属性实现属性访问控制 注意事项 描述符类型限制性能考虑继承关系处理错误处理 最佳实践 合理使用缓存避免复杂计算注意默认值做好错误处理
10. 深入理解 Object.defineProperty()
10.1 基础概念详解
Object.defineProperty() 是 JavaScript 中用于在对象上定义新属性或修改现有属性的方法。它允许精确控制属性的特性。
// 基本语法
Object.defineProperty(obj, prop, descriptor)// 参数说明
// obj: 要定义属性的对象
// prop: 要定义或修改的属性名
// descriptor: 属性描述符对象10.2 属性描述符详解
属性描述符分为两种类型数据描述符和访问器描述符。
数据描述符的完整选项:
const obj {};
Object.defineProperty(obj, name, {value: John, // 属性值writable: true, // 是否可写enumerable: true, // 是否可枚举configurable: true // 是否可配置
});访问器描述符的完整选项:
const obj {_name: John
};
Object.defineProperty(obj, name, {get() {console.log(Getting value);return this._name;},set(value) {console.log(Setting value to, value);this._name value;},enumerable: true,configurable: true
});10.3 常见使用场景
只读属性:
const obj {};
Object.defineProperty(obj, readonly, {value: I am read-only,writable: false,enumerable: true,configurable: false
});obj.readonly New value; // 无效
console.log(obj.readonly); // I am read-only不可枚举属性:
const obj {};
Object.defineProperty(obj, hidden, {value: You cannot see me,enumerable: false
});console.log(Object.keys(obj)); // []
console.log(obj.hidden); // You cannot see me计算属性:
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); // SmithVue 双向绑定实现:
function observe(obj) {if (!obj || typeof obj ! object) return;// 遍历对象的每个属性Object.keys(obj).forEach(key {let value obj[key];let dep new Dep(); // 依赖收集器Object.defineProperty(obj, key, {get() {// 收集依赖if (Dep.target) {dep.addDep(Dep.target);}return value;},set(newValue) {if (value newValue) return;value newValue;// 通知所有依赖进行更新dep.notify();}});// 递归观察子属性if (typeof value object) {observe(value);}});
}// 使用示例
const data {user: {name: John,age: 20}
};observe(data);
// 现在 data 对象的所有属性都是响应式的10.4 注意事项和最佳实践
描述符限制:
// 不能同时使用数据描述符和访问器描述符
Object.defineProperty(obj, prop, {value: 123,get() { return 123; } // 错误
});性能优化:
// 批量定义属性
Object.defineProperties(obj, {prop1: {value: 123,writable: true},prop2: {get() { return this.prop1 * 2; }}
});默认值处理:
// 所有描述符属性默认为 false
Object.defineProperty(obj, prop, {value: 123// writable: false// enumerable: false// configurable: false
});