ES6中没有官方的私有属性语法,但是我们可以使用以下几种方式来模拟实现:
1. 命名约定
将私有属性命名以下划线“_”开头,约定为私有属性,外部不应直接访问。这种方式不需要额外的代码,只需要在类中按照约定命名私有属性即可。例如:
class MyClass { constructor() { this._privateProperty = '私有属性'; } getPrivateProperty() { return this._privateProperty; }}
这种方式的缺点是没有实质性的保护作用,外部仍然可以通过直接访问属性来获取私有属性的值。
2. Symbol私有属性
使用Symbol作为私有属性的键,这样外部就无法直接访问私有属性。例如:
const _privateKey = Symbol('私有属性');class MyClass { constructor(privateValue) { this[_privateKey] = privateValue; } getPrivateValue() { return this[_privateKey]; }}
这种方式可以保护私有属性不被外部直接访问,但是如果外部知道了Symbol值,仍然可以访问私有属性。
3. WeakMap私有属性
使用WeakMap存储私有属性,外部无法直接访问WeakMap中的属性。例如:
const privateMap = new WeakMap();class MyClass { constructor(privateValue) { privateMap.set(this, privateValue); } getPrivateValue() { return privateMap.get(this); }}
这种方式可以保护私有属性不被外部直接访问,而且外部无法获取WeakMap的键。
4. 闭包实现私有属性
使用闭包将私有属性封装在类中,外部无法访问。例如:
class MyClass { constructor(privateValue) { this.getPrivateValue = function() { return privateValue; }; }}
这种方式可以保护私有属性不被外部直接访问,但是每创建一个实例都会新建一个函数,会占用额外的内存空间。
5. Proxy实现私有属性
使用Proxy代理类的属性访问,可以实现私有属性。例如:
const privateHandler = { get(target, prop) { if (prop.startsWith('_')) { throw new Error('私有属性,禁止访问!'); } return target[prop]; }, set(target, prop, value) { if (prop.startsWith('_')) { throw new Error('私有属性,禁止赋值!'); } target[prop] = value; return true; }};class MyClass { constructor() { this.publicProperty = '公有属性'; this._privateProperty = '私有属性'; return new Proxy(this, privateHandler); }}
这种方式可以保护私有属性不被外部直接访问,而且可以控制是否允许赋值。但是这种方式需要额外的代码来实现。
综上所述,以上方法均可以实现类的私有属性,具体选择哪种方式取决于应用场景和个人偏好。