- 基本用法
// get和set语法将对象属性绑定到函数,访问/赋值时函数会被调用 let nums = { all: [], get curr () { let len = this.all.length return this.all[len - 1] }, set curr (val) { this.all.push(val) } } nums.curr // undefined,调用getter nums.curr = 1 // 调用setter nums.curr // 1 // 相当于创建了一个伪属性(pseudo-property),可以使用delete删除 delete nums.curr
- 属性名要求是number/string/symbol
let s = Symbol('foo') let nums = { getter 1 () {return 1}, getter ['a' + 'b'] () {return 2}, getter [s] () {return 3} } Object.getOwnPropertyNames(nums) // ['1', 'ab'],属性'1'会提到最前面 Object.getOwnPropertySymbols(nums) // [Symbol(foo)]
- getter没有参数,setter有一个参数
let nums = { all: [], // SyntaxError: getter must not have any formal parameters. get curr (x) { let len = this.all.length return this.all[len - 1] }, // SyntaxError: setter must have exactly one formal parameter. set curr (val, x) { this.all.push(val) } }
- 不能存在同名属性
It must not appear in an object literal with another get/set or with a data entry for the same property.
(1)同名属性在getter/setter前面
// 存在同名属性并没有报错 let nums = { all: [], curr: 2, // 在getter/setter前面 get curr () { let len = this.all.length return this.all[len - 1] }, set curr (val) { this.all.push(val) } } curr, all // undefined, [] nums.curr = 4 // getter/setter都正常执行 curr, all // 4, [4]
(2)同名属性在getter/setter后面
let nums = { all: [], get curr () { let len = this.all.length return this.all[len - 1] }, set curr (val) { this.all.push(val) }, curr: 2, // 在getter/setter后面 } curr, all // undefined, [] nums.curr = 4 // 没有执行setter,返回了getter curr, all // undefined, []
(3)存在同名getter/setter
let nums = { all: [], get curr () { let len = this.all.length return this.all[len - 1] }, get curr () { return 3 }, set curr (val) { this.all.push(val) }, set curr (val) { this.all.push(val + 1) } } // 后面的getter/setter生效 curr, all // 3, [] nums.curr = 4 curr, all // 3, [5]
- 已存在的对象添加getter/setter
Object.definedProperty(nums, 'curr', { configurable: true, // 默认false enumerable: true, // 默认false get curr () { let len = this.all.length return this.all[len - 1] }, set curr (val) { this.all.push(val) } }) // 对象字面量中定义的getter/setter的属性描述符(property descriptor) Object.getOwnPropertyDescriptor(nums, 'curr') { configurable: true, enumerable: true, get: [Function get], set: [Function set] }
- get Vs. definedProperty
class Nums { get curr () { return 1 } } let n = new Nums() Object.definedProperty(n, 'foo', { configurable: true, enumerable: true, get () {return 1} }) n.hasOwnProperty('foo') // true Object.getPropertyOf(n).hasOwnProperty('curr') // true
- getter的懒求值和缓存
某些属性计算的代价比较高,如花费大量内存和CPU时间的操作;
属性值不是立即需要,甚至是不需要的,延迟计算;
计算多次且属性值没有改变时,不应该重新计算。
let o = { get foo () { return 1 + 2 } } o.foo // 3, 此时才会计算(1 + 2)
文章来源: ES6的getter和setter