Getter / Setter 基础知识

一、定义

GetterSetter 是 JavaScript 中访问器属性(Accessor Properties)的两个组成部分,用于拦截对象属性的读取写入操作。

名称 触发时机 作用
Getter 读取属性值时 返回属性值(可加工处理后返回)
Setter 修改属性值时 接收新值,可执行额外操作(如日志、校验、触发更新)

二、来源

  • 2009年 ES5 发布,正式引入 Object.defineProperty和 getter/setter
  • 早于 Vue 诞生(Vue 1.0 发布于 2014年)
  • 许多编程语言都有类似概念(Java、C#、Python 等)

三、两种写法

写法1:对象字面量语法

const obj = {
    _name: '张三',

    get name() {
        return this._name + '先生'   // 可加工处理
    },

    set name(value) {
        console.log('有人修改了 name')
        this._name = value
    }
}

obj.name       // 触发 getter → 返回 '张三先生'
obj.name = '李四'  // 触发 setter → 打印日志,_name 变为 '李四'

写法2:Object.defineProperty(Vue2 采用的方式)

const obj = {}
Object.defineProperty(obj, 'name', {
    get() {
        return this._name
    },
    set(val) {
        console.log('name 被修改了')
        this._name = val
    }
})

四、与普通数据属性的区别

对比项 数据属性(Data Property) 访问器属性(Accessor Property)
定义方式 obj.name = '张三' get name() / set name()
读取时 直接返回值 执行 getter 函数
修改时 直接赋值 执行 setter 函数
额外操作 无法拦截 可添加日志、校验、触发更新等

五、Vue 中的应用

Vue2 利用 Object.definePropertydata 中每个属性添加 getter/setter:

  • Getter:读取属性时收集依赖(记录哪些地方用到了这个属性)
  • Setter:修改属性时通知更新(触发视图重新渲染)
// Vue 内部简化示意
Object.defineProperty(data, 'name', {
    get() {
        dep.depend()      // 收集依赖
        return value
    },
    set(newVal) {
        value = newVal
        dep.notify()      // 通知更新
    }
})

六、注意事项

  1. getter 不能有参数,setter 只能有一个参数(新值)
  2. 同一个属性不能同时拥有 getter/setter 和数据值(要么是访问器属性,要么是数据属性)
  3. getter/setter 中的 this 指向定义它们的对象
  4. 在 getter/setter 内部访问自身属性要小心无限递归(应使用下划线前缀的私有变量存储实际值)

七、一句话总结

Getter 和 Setter 是 JavaScript 原生的”读/写拦截器”,Vue 借它们实现了”数据变了,视图自动更新”的响应式魔法。