有没有办法使 javascript 对象 属性 私有化?
Is there a way to make private a javascript object property?
如何将 javascript 对象设为私有 属性,以便 Object.keys()
和 Object.getOwnPropertyNames()
不会 return 那个 属性?
这是一个 class 使用闭包和 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'))
How can I make private a JavaScript object property so that Object.keys()
and Object.getOwnPropertyNames()
don't return that property?
您使用的是术语 "private",然后您描述的行为与该词通常所指的行为不同。
"Private" 通常表示 属性 或值无法从对象外部访问。未被 Object.keys()
报告被称为不是 enumerable。
由defineProperty
定义的任何属性在默认情况下都是不可枚举的,所以
Object.defineProperty(obj, 'privateField', {value: 5});
或者,如
中那样明确指定
Object.defineProperty(obj, 'privateField', {value: 5, enumerable: false});
将导致 obj.privateField
不可枚举,因此不包含在 Object.keys()
的结果中。
如果您真的希望 属性 在通常意义上是私有的——这意味着它不能从对象的外部方法访问——那么一些选项包括:
使用 TypeScript 及其 private
关键字。这将导致尝试的外部访问引发编译时错误。
等待 private fields 的 JS 增强功能,可能采用 #foo
.
的形式
在闭包中使用变量来表示私有值。
为 属性 名称使用符号,尽管这可能无法确保真正的隐私。
使用 WeakMap
表示私有 属性,如另一个答案中所建议。
按照评论中的建议将您的对象包裹在 Proxy
中,这会阻止对私有 属性.
的访问
有关更多详细信息和想法,请参阅 this question。
如何将 javascript 对象设为私有 属性,以便 Object.keys()
和 Object.getOwnPropertyNames()
不会 return 那个 属性?
这是一个 class 使用闭包和 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'))
How can I make private a JavaScript object property so that
Object.keys()
andObject.getOwnPropertyNames()
don't return that property?
您使用的是术语 "private",然后您描述的行为与该词通常所指的行为不同。
"Private" 通常表示 属性 或值无法从对象外部访问。未被 Object.keys()
报告被称为不是 enumerable。
由defineProperty
定义的任何属性在默认情况下都是不可枚举的,所以
Object.defineProperty(obj, 'privateField', {value: 5});
或者,如
中那样明确指定Object.defineProperty(obj, 'privateField', {value: 5, enumerable: false});
将导致 obj.privateField
不可枚举,因此不包含在 Object.keys()
的结果中。
如果您真的希望 属性 在通常意义上是私有的——这意味着它不能从对象的外部方法访问——那么一些选项包括:
使用 TypeScript 及其
private
关键字。这将导致尝试的外部访问引发编译时错误。等待 private fields 的 JS 增强功能,可能采用
#foo
. 的形式
在闭包中使用变量来表示私有值。
为 属性 名称使用符号,尽管这可能无法确保真正的隐私。
使用
WeakMap
表示私有 属性,如另一个答案中所建议。按照评论中的建议将您的对象包裹在
Proxy
中,这会阻止对私有 属性. 的访问
有关更多详细信息和想法,请参阅 this question。