
▌这玩意是啥?
封装就像给你的钱包上拉链——钱(数据)放里面,只能通过拉链(方法)拿。
你不会直接把钞票散桌上,对吧?所以我们让外部代码也不能乱伸手进来改。
抽象呢,更像自动售货机——你只管投币、按按钮,饮料自己掉出来。
至于它怎么感应硬币、控制电机,那些复杂的逻辑都藏在机器里面。
这两个概念放一起,就是让复杂的内部逻辑“藏”起来,只留下简单好用的接口。
▌能干啥?
简单点讲:让代码更安全、更好维护。
封装可以防止外部代码乱改内部数据,比如直接把余额改成负数。 抽象可以把一堆细节打包成一个动作,比如“存钱”这件事—— 你只管 deposit(500),不用管它是加了多少、怎么记录日志的。
这样一来,别人动不了你的“钱包”,用起来也更安心。 以后要改逻辑,也只动内部代码,不影响别人调用的部分。
▌咋用?
在 JS 里,ES2022 以后其实挺好封装的,用 # 定义私有字段就行:
用
#定义私有属性,比如#balance,外面看不见、改不了。需要内部记录点事,就写私有方法,比如
#recordTransaction()。把外部能用的操作,比如
deposit()、withdraw(),当成窗口。用
constructor初始化状态,防止乱糟糟的值流进来。想快速建对象,可以用静态方法(
static)当“工厂函数”。
比如这段代码👇(银行账户就是个很典型的封装例子):
class BankAccount {
// 私有属性
#balance;
#holder;
#transactionHistory;
constructor(initialBalance, accountHolder) {
this.#balance = initialBalance;
this.#holder = accountHolder;
this.#transactionHistory = [];
}
// 私有方法
#recordTransaction(type, amount) {
this.#transactionHistory.push({
holder: this.#holder,
type,
amount,
balance: this.#balance,
date: newDate(),
});
}
// 公共方法
deposit(amount) {
if (amount > 0) {
this.#balance += amount;
this.#recordTransaction('存款', amount);
return`${this.#holder} 存款成功,余额:${this.#balance} 元`;
}
return'存款金额必须大于 0';
}
withdraw(amount) {
if (amount > 0 && amount <= this.#balance) {
this.#balance -= amount;
this.#recordTransaction('提款', amount);
return`${this.#holder} 提款成功,余额:${this.#balance} 元`;
}
return'提款金额无效或余额不足';
}
// 只读接口
getBalance() {
returnthis.#balance;
}
getHistory() {
return [...this.#transactionHistory];
}
static createSavingsAccount(holder) {
returnnew BankAccount(0, holder);
}
}有了这套机制,外部就算想改 #balance 也改不了:
const myAccount = new BankAccount(1000, '小明');
console.log(myAccount.deposit(500)); // ✅ 小明存款成功,余额:1500 元
console.log(myAccount.#balance); // ❌ 报错:私有字段无法访问▌记得一点
封装不是为了“藏私”,是为了“省心”—— 不让别人乱动你的变量,也不让未来的你掉坑。 写给人看的代码,也得替自己留点活路。
#JavaScript #面向对象 #封装与抽象 #前端笔记 #代码碎碎念 #ES6+
3万+

被折叠的 条评论
为什么被折叠?



