5月27日 01:05

什么是 defineProperty 方法?什么时候需要用到它?

Object.defineProperty(obj, prop, descriptor) 让你精确控制对象属性的行为——是否可写、可枚举、可配置,还能定义 getter/setter。

javascript
const obj = {}; Object.defineProperty(obj, 'name', { value: '张三', writable: false, // 不可修改 enumerable: true, // for...in 可遍历 configurable: false // 不可删除、不可再次配置 });

核心价值在于拦截属性的读写。Vue 2 的响应式系统就是用 Object.defineProperty 劫持对象属性的 getter/setter,才能在数据变化时通知视图更新。

追问

defineProperty 和直接赋值有什么区别?

直接赋值 obj.x = 1 创建的属性,writableenumerableconfigurable 默认都是 trueget/setundefineddefineProperty 创建的属性,不显式指定的描述符默认都是 false

Vue 3 为什么换成 Proxy?

defineProperty 有硬伤:无法检测属性的添加/删除(所以 Vue 2 需要 $set$delete),对数组索引和 length 的拦截有坑。Proxy 能拦截 13 种操作,包括属性增删、indeleteapply,不需要遍历对象属性递归劫持。

什么场景下需要把属性设成不可枚举?

  • 给原型添加方法时(不想污染 for...in
  • 框架内部属性(如 Vue 的 __ob__
  • 任何不希望被 JSON.stringify 序列化或被 Object.keys 返回的属性
标签:JavaScript前端