为何JavaScript中Getter在不同代码示例中的表现存在差异?
为什么Getter在不同代码示例中的表现不同?
在探究setter的意义时,我发现了一个疑问:为什么Getter在不同代码里的表现不一样?下面是三个典型场景:
场景一:普通对象属性可直接修改
function Car() { const fuel = 50 return { fuel, } } const car = Car() console.log(car.fuel) // 50 car.fuel = 3000 console.log(car.fuel) // 3000
这里Car函数返回的对象,其fuel属性是直接赋值了函数内部const fuel的初始值,本质是普通对象属性,和原函数内的fuel变量已经没有关联,所以外部可以直接修改。
场景二:Getter保护内部变量不可修改
function Car() { const fuel = 50 return { get fuel() { return fuel }, } } const car = Car() car.fuel = 3000 console.log(car.fuel) // 50
这里给返回对象添加了fuel的Getter方法,它返回的是函数作用域内的const fuel——这个变量被函数闭包保护,外部无法直接访问。当你尝试给car.fuel赋值时,其实只是给对象新增了一个同名的普通属性,但Getter的优先级高于普通属性,所以访问car.fuel时依然会调用Getter,返回最初的50。
场景三:Getter关联对象自身属性,修改关联值会同步变化
const person = { _firstName: 'John', _lastName: 'Doe', get fname() { return this._firstName; } } console.log(person.fname); // prints 'John' person._firstName = 'Juan'; console.log(person.fname); //prints 'Juan'
这里的Getter返回的是对象自身的_firstName属性,并没有对这个属性做封装保护。当你直接修改person._firstName时,Getter每次调用都会读取最新的属性值,所以返回结果会跟着变化。
本质原因总结
Getter的表现差异核心在于它关联的数据源和是否有配套Setter:
- 场景一根本没用到Getter,只是普通属性赋值;
- 场景二利用闭包把数据源(
const fuel)放在函数私有作用域,且没有设置Setter,外部无法修改私有数据源; - 场景三的数据源是对象自身的可写属性,外部能直接修改这个数据源,自然会影响Getter的返回值。
Getter的核心价值之一是封装内部状态,避免外部直接修改关键数据;如果只是用来做属性别名或读取公开属性,就会出现场景三的情况。
内容的提问来源于stack exchange,提问作者user3303019
相关产品推荐
相关产品推荐

