繁体   English   中英

有没有办法将javascript对象属性设为私有?

[英]Is there a way to make private a javascript object property?

如何将javascript对象属性Object.keys()私有,以便Object.keys()Object.getOwnPropertyNames()不返回该属性?

如何将JavaScript对象属性Object.keys()私有,以便Object.keys()Object.getOwnPropertyNames()不返回该属性?

您使用的是“私人”一词,然后描述的行为与该词通常所指的行为不同。

“私有”通常表示无法从对象外部访问该属性或值。 没有被Object.keys()报告称为不可枚举

默认情况下, defineProperty定义的任何属性都是不可枚举的,因此

Object.defineProperty(obj, 'privateField', {value: 5});

或者,明确指定为

Object.defineProperty(obj, 'privateField', {value: 5, enumerable: false});

将导致obj.privateField不可枚举,因此不包含在Object.keys()的结果中。

如果您确实希望按通常的意义将属性设为私有-意味着无法从对象的外部方法访问它-那么一些选项包括:

  1. 使用TypeScript及其private关键字。 这将导致尝试进行的外部访问引发编译时错误。

  2. 等待私有字段的 JS增强,这些增强可以采用#foo的形式。

  3. 在闭包内使用变量表示私有值。

  4. 使用符号作为属性名称,尽管这可能无法确保真正的隐私。

  5. 根据另一个答案的建议,使用WeakMap表示私有属性。

  6. 如注释中所建议,将对象包装在Proxy中,这会阻止对私有属性的访问。

有关更多详细信息和想法,请参阅此问题

这是使用闭包和WeakMap实现私有属性的类的演示:

 const Private = function () { const weakPrivateScope = new WeakMap() return class Private { constructor() { weakPrivateScope.set(this, {}) } get(propertyName) { return weakPrivateScope.get(this)[propertyName] } set(propertyName, value) { return weakPrivateScope.get(this)[propertyName] = value } has(propertyName) { return Object.keys(weakPrivateScope.get(this)).includes(propertyName) } delete(propertyName) { return delete weakPrivateScope.get(this)[propertyName] } } }() class MyClass extends Private { constructor() { super() this.myPrivateProperty = 'initial value' } get myPrivateProperty() { return this.get('myPrivateProperty') } set myPrivateProperty(value) { return this.set('myPrivateProperty', value) } } let myObject = new MyClass() console.log('able to access and update value normally:') console.log('myObject.myPrivateProperty') console.log(myObject.myPrivateProperty) console.log('myObject.myPrivateProperty = "new value"') myObject.myPrivateProperty = 'new value' console.log(myObject.myPrivateProperty) console.log('keys() and getOwnPropertyNames() do not get the property:') console.log(Object.keys(myObject)) console.log(Object.getOwnPropertyNames(myObject)) console.log('you can check for existence and delete the property as well:') console.log('myObject.has("myPrivateProperty")') console.log(myObject.has('myPrivateProperty')) console.log('myObject.delete("myPrivateProperty")') myObject.delete('myPrivateProperty') console.log(myObject.has('myPrivateProperty')) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM