当我们在使用面向对象程序设计时,往往需要实现类的私有变量,以限制对变量的直接访问,防止出现意外修改。ES6中,有多种方式可以实现类的私有变量。
一种常见的方式是使用Symbol实现,具体实现方法如下:
- 首先定义一个Symbol类型的变量,在模块或类的顶层定义,确保其唯一性,比如:
const _privateVariable = Symbol('privateVariable');
- 在类的构造函数中将私有变量绑定到this上,从而使得该变量变成了该类实例的属性。
class Example {
constructor(value) {
this[_privateVariable] = value;
}
}
- 接着可以在该类的方法中使用私有变量,如:
class Example {
constructor(value) {
this[_privateVariable] = value;
}
getValue() {
return this[_privateVariable];
}
}
这种方法使用了Symbol的唯一性,确保每个类实例都有自己的私有变量,并且不会被外部代码篡改。
另一种方法是使用WeakMap实现,它的原理是将私有变量作为WeakMap的键,确保仅在该类实例被垃圾回收时才会被清除。具体实现方法如下:
- 定义一个空的WeakMap对象:
const _privateVariables = new WeakMap();
- 在类的构造函数中将私有变量添加到WeakMap对象中,从而使得该变量变成了该类实例的私有变量。
class Example {
constructor(value) {
_privateVariables.set(this, value);
}
}
- 在该类的方法中可以通过WeakMap对象获取私有变量,如:
class Example {
constructor(value) {
_privateVariables.set(this, value);
}
getValue() {
return _privateVariables.get(this);
}
}
这种方法保护了私有变量,并且在垃圾回收时自动清除私有变量。
示例1:
const _privateVariable = Symbol('privateVariable');
class Example {
constructor(value) {
this[_privateVariable] = value;
}
getValue() {
return this[_privateVariable];
}
}
let example1 = new Example('private1');
console.log(example1.getValue()); // 返回'private1'
example1[_privateVariable] = 'public1';
console.log(example1.getValue()); // 返回'private1',因为私有变量并没有被更改
在示例1中,我们使用了Symbol来实现私有变量,确保了其唯一性。在类实例化时,私有变量被绑定到对应实例中,保证了私有变量的访问性和独立性。当我们尝试篡改私有变量时,由于其唯一性无法被更改,因此即便尝试也无法访问到被保护的值。
示例2:
const _privateVariables = new WeakMap();
class Example {
constructor(value) {
_privateVariables.set(this, value);
}
getValue() {
return _privateVariables.get(this);
}
}
let example1 = new Example('private1');
console.log(example1.getValue()); // 返回'private1'
example1.value = 'public1';
console.log(example1.getValue()); // 返回'private1',因为私有变量并没有被更改
在示例2中,我们使用了WeakMap来实现私有变量,确保了私有变量的安全性和私密性。在类实例化时,私有变量被加到WeakMap中,并且同样保证了私有变量的独立性和访问性。与示例1不同的是,在尝试篡改私有变量时,我们注入的public1无法更改WeakMap中私有变量的键名和值,因此例子中为'private1'的值得到保障并被返回。
本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!