[英]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()
的结果中。
如果您确实希望按通常的意义将属性设为私有-意味着无法从对象的外部方法访问它-那么一些选项包括:
使用TypeScript及其private
关键字。 这将导致尝试进行的外部访问引发编译时错误。
等待私有字段的 JS增强,这些增强可以采用#foo
的形式。
在闭包内使用变量表示私有值。
使用符号作为属性名称,尽管这可能无法确保真正的隐私。
根据另一个答案的建议,使用WeakMap
表示私有属性。
如注释中所建议,将对象包装在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.