2022-08-14 14:36:40
Object.defineProperty() 是 JavaScript 中用于直接在对象上定义新属性或修改现有属性的方法,它是实现数据响应式(如 Vue 2.0)的核心机制。以下是关键知识点总结:
1. 基本语法Object.defineProperty(obj, prop, descriptor)注意:数据描述符和存取描述符不能混用,否则会报错。
3. 关键特性与示例不可写属性const obj = {};Object.defineProperty(obj, 'name', { value: 'Ken', writable: false });obj.name = 'New'; // 非严格模式静默失败,严格模式报错console.log(obj.name); // 'Ken'不可枚举属性const obj = {};Object.defineProperty(obj, 'secret', { value: '123', enumerable: false });console.log(Object.keys(obj)); // []不可配置属性const obj = {};Object.defineProperty(obj, 'id', { value: 1, configurable: false });delete obj.id; // 静默失败Object.defineProperty(obj, 'id', { enumerable: true }); // 报错自定义 Getter/Setterconst obj = { _name: 'Ken' };Object.defineProperty(obj, 'name', { get() { return this._name; }, set(newVal) { this._name = `Name: ${newVal}`; }});obj.name = 'NaNa';console.log(obj.name); // 'Name: NaNa'4. 高级用法继承属性控制通过 Object.create(null) 创建无原型链的对象,避免继承属性干扰:
const obj = Object.create(null);Object.defineProperty(obj, 'key', { value: 'static' });冻结原型链防止修改 Object.prototype 的默认属性:
(Object.freeze || Object)(Object.prototype);Symbol 属性Symbol 属性也可被定义为可枚举:
const obj = {};Object.defineProperty(obj, Symbol('id'), { value: 1, enumerable: true });5. Vue 2.0 响应式原理Vue 通过 Object.defineProperty() 拦截数据属性的 get 和 set,实现依赖收集和派发更新:
function defineReactive(obj, key, val) { const dep = new Dep(); // 依赖收集器 Object.defineProperty(obj, key, { get() { dep.depend(); // 收集依赖 return val; }, set(newVal) { if (newVal === val) return; val = newVal; dep.notify(); // 通知更新 } });}6. 注意事项Object.defineProperty() 提供了精细控制对象属性的能力,是理解 JavaScript 对象行为和框架响应式原理的基础。通过合理配置描述符,可以实现数据保护、动态计算属性等高级功能。