所谓私有方法和私有属性,是指只能在类的内部访问的方法和
属性,外部不能访问。
这样做是常见需求,有利于代码的封装,但 ES6 不提供,只能
通过方法模拟实现。
以下是几种方法:
class Point{
//共有方法
foo(baz){
this._bar(baz);
}
//私有方法
_bar(baz){
return this.snag = baz;
}
//...
}
上面代码中,_bar 方法前面的下划线,表示这是一个只限于内
部使用的私有方法。但是这种命名是不保险的,在类的外部还
是可以调用该方法。
因为模块内部的所有方法都是对外可见的
class Point{
//共有方法
foo(baz){
//使得bar实际上成为了当前模块的私有方法。
_bar.call(this, baz)
}
//...
}
//私有方法
function _bar(baz){
return this.snag = baz;
}
上面的方法中,foo 是公开方法,内部调用了
bar.call(this,baz)。这使得 bar 实际上成为了当前模块的私有方
法。
将私有方法的名字命名为一个 Symbol 值。
const bar = Symbol('bar');
const snag = Symbol('snag');
class Point{
// 共有方法
foo(baz){
this[bar](baz);
}
// 私有方法
[bar](baz){
return this[snag] = baz
}
//...
}
上述代码中, bar 和 snag 都是 Symbol 值,一般情况下无法获
取他们,因此到达了私有属性和私有方法的效果。但是也不是
绝对不行,Reflect.ownKeys()依然可以拿到他们
const obj = new Point();
Reflect.ownKeys(Point.prototype);
console.log(Reflect.ownKeys(Point.prototype));
// [ 'constructor', 'foo', Symbol(bar) ]
class Point {
#count = 0;
get value(){
return this.#count;
}
foo(){
this.#count++;
}
//...
}
const obj = new Point();
obj.#count; //报错
obj.#count = 23; // 报错
上面的代码在类的外面,读取私有属性,就会报错。
而且在类里面#count 和 count 属于两个不同的属性。
这种写法不仅可以写私有属性,还可以用来写私有方法。
class Foo {
#a;
#b;
constructor(a, b) {
this.#a = a;
this.#b = b;
}
#sum() {
return #a + #b;
}
printSum() {
console.log(this.#sum());
}
}