# 对象和数据结构
# 多使用 getter 和 setter
通常来说,使用 getter 去访问一个对象的属性要比直接用访问运算符要好一些。你可能会问为什么,这里是我给出的一些回答:
- 当你想要拓展访问某个对象属性的行为的时候,不再需要去整个代码库里找到每一个访问对象的地方(通常这个过程是比较痛苦的,而且也容易遗漏)。
- 在进行
set
操作的时候,更容易地添加一些校验行为。 - 封装对象内部行为。
- 在访问对象属性和设置对象属性的时候非常方便的添加 log。
- 当我们对象上的属性是来自服务端的时候,可以给我们的对象属性实现懒加载访问。
👎 Bad:
function makeBankAccount() {
// ...
return {
balance: 0,
// ...
}
}
const account = makeBankAccount()
account.balance = 100
👍 Good:
function makeBankAccount() {
// 内部私有 balance
let balance = 0
// 我们所说的 `getter`,对外暴露出去
function getBalance() {
return balance
}
// 我们所说的 `setter`,对外暴露出去
function setBalance(amount) {
// 我们可以在这里做一些数据的校验
balance = amount
}
return {
// ...
getBalance,
setBalance,
}
}
const account = makeBankAccount()
account.setBalance(100)
# 让对象有私有属性
我们也可以通过闭包来完成这件事情(在 ES5 及以下)
👎 Bad:
const Employee = function (name) {
this.name = name
}
Employee.prototype.getName = function getName() {
return this.name
}
const employee = new Employee('John Doe')
console.log(`Employee name: ${employee.getName()}`) // Employee name: John Doe
delete employee.name
console.log(`Employee name: ${employee.getName()}`) // Employee name: undefined
👍 Good:
function makeEmployee(name) {
return {
getName() {
return name
},
}
}
const employee = makeEmployee('John Doe')
console.log(`Employee name: ${employee.getName()}`) // Employee name: John Doe
delete employee.name
console.log(`Employee name: ${employee.getName()}`) // Employee name: John Doe