Getter / Setter 基础知识
一、定义
Getter 和 Setter 是 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.defineProperty 为 data 中每个属性添加 getter/setter:
- Getter:读取属性时收集依赖(记录哪些地方用到了这个属性)
- Setter:修改属性时通知更新(触发视图重新渲染)
// Vue 内部简化示意
Object.defineProperty(data, 'name', {
get() {
dep.depend() // 收集依赖
return value
},
set(newVal) {
value = newVal
dep.notify() // 通知更新
}
})
六、注意事项
- getter 不能有参数,setter 只能有一个参数(新值)
- 同一个属性不能同时拥有 getter/setter 和数据值(要么是访问器属性,要么是数据属性)
- getter/setter 中的
this指向定义它们的对象 - 在 getter/setter 内部访问自身属性要小心无限递归(应使用下划线前缀的私有变量存储实际值)
七、一句话总结
Getter 和 Setter 是 JavaScript 原生的”读/写拦截器”,Vue 借它们实现了”数据变了,视图自动更新”的响应式魔法。
