模拟实现私有变量(面试加分项)
// 私有变量的实现
// v1. 基础实现
class Example {
constructor(name){
this._private = name;
}
getName(){
return this._private;
}
}
let ex = new Example('private1');
console.log(ex.getName(), ex._private); // private private
let ex1 = new Example('private2');
console.log(ex1.getName(), ex1._private); // private private
// TODO: 主要问题
// 1. 外部可以访问和修改
// 2. 语言没有配合的机制,for In可以枚举出来
// 3. 命名冲突
// v2. 使用闭包来实现
// v2.1
class Example02 {
constructor(name){
let _private = '';
_private = name;
this.getName = function () {
return _private;
}
}
}
let ex01 = new Example02('private1');
console.log(ex01.getName(), ex01._private); // private private
let ex02 = new Example02('private2');
console.log(ex02.getName(), ex02._private); // private private
// 优点:1. 没有命名冲突, 2.外部无法直接访问和修改
// TODO: 缺点
// 1. constructor 的逻辑变得复杂。构造函数应该只做对象初始化的事情,现在为了实现私有变量,必须包含部分方法的实现,代码组织上略不清晰。
// 2. 方法存在于实例,而非原型上,子类也无法使用 super 调用
// 3. 构建增加一点点开销
// v2.2 代码优化
const Example03 = (function () {
let _private = '';
class Example03 {
constructor() {
_private = 'private';
}
getName(){
return _private;
}
}
return Example03;
})();
let ex3 = new Example03();
console.log(ex3.getName(), ex3._private) // private undefined
// 优点: 1. 没有命名冲突, 2. 外部无法访问和修改
// TODO: 缺点:1. 写法复杂 2. 构建开销
// v3. 使用Symbol来实现
const Example4 = (function () {
// 每个Symbol实际上都是唯一的
let _private = Symbol('private');
class Example4 {
constructor(props) {
this[_private] = 'private';
}
getName(){
return this[_private];
}
}
return Example4;
})();
// 优点: 1.没有命名冲突 2.外部无法访问和修改 3. 没有性能损失
// 缺点: 写法稍微复杂,兼容性还好
// v4. 使用WeakMap实现
const _private = new WeakMap();
class Example5 {
constructor(){
_private.set(this, 'private');
}
getName(){
return _private.get(this);
}
}
let ex5 = new Example5();
console.log(ex5.getName(), ex5.name)
// 上面的代码封装
const Example5 = (function () {
const _private = new WeakMap();
class Example5{
constructor(){
_private.set(this, 'private');
}
getName(){
return _private.get(this);
}
}
return Example5;
})();
// v5. 最新提案
class Point {
#x;
#y;
constructor(x, y){
this.#x = x;
this.#y = y;
}
equals(point){
return this.#x === point.#x && this.#y === point.#y;
}
}
评论
填写昵称与邮箱即可评论,无需登录。