5月27日 01:05
什么是 defineProperty 方法?什么时候需要用到它?
Object.defineProperty(obj, prop, descriptor) 让你精确控制对象属性的行为——是否可写、可枚举、可配置,还能定义 getter/setter。
javascriptconst obj = {}; Object.defineProperty(obj, 'name', { value: '张三', writable: false, // 不可修改 enumerable: true, // for...in 可遍历 configurable: false // 不可删除、不可再次配置 });
核心价值在于拦截属性的读写。Vue 2 的响应式系统就是用 Object.defineProperty 劫持对象属性的 getter/setter,才能在数据变化时通知视图更新。
追问
defineProperty 和直接赋值有什么区别?
直接赋值 obj.x = 1 创建的属性,writable、enumerable、configurable 默认都是 true,get/set 是 undefined。defineProperty 创建的属性,不显式指定的描述符默认都是 false。
Vue 3 为什么换成 Proxy?
defineProperty 有硬伤:无法检测属性的添加/删除(所以 Vue 2 需要 $set、$delete),对数组索引和 length 的拦截有坑。Proxy 能拦截 13 种操作,包括属性增删、in、delete、apply,不需要遍历对象属性递归劫持。
什么场景下需要把属性设成不可枚举?
- 给原型添加方法时(不想污染
for...in) - 框架内部属性(如 Vue 的
__ob__) - 任何不希望被
JSON.stringify序列化或被Object.keys返回的属性