如何使私人的JavaScript對象屬性,以便Object.keys()
和Object.getOwnPropertyNames()
不返回該屬性?有沒有辦法讓私人的JavaScript對象屬性?
回答
如何讓私人JavaScript對象屬性,以便
Object.keys()
和Object.getOwnPropertyNames()
唐不返回那個財產?
您使用的術語「私人」,然後你描述的行爲是不同於那個詞通常的意思。
「私有」通常表示該屬性或值不能從對象外部訪問。沒有被Object.keys()
報告被稱爲不是enumerable。
通過defineProperty
定義的任何屬性將默認爲不枚舉,所以
Object.defineProperty(obj, 'privateField', {value: 5});
,或者顯式地將其指定爲在
Object.defineProperty(obj, 'privateField', {value: 5, enumerable: false});
將導致obj.privateField
暫時不枚舉的,並且因此不包括在Object.keys()
的結果。
如果你真的想要一個特性,在通常意義上的私人 - 這意味着它不能從對象上的方法外訪問 - 然後一些選項包括:
使用打字稿及
private
關鍵字。這將導致嘗試的外部訪問引發編譯時錯誤。等待JS增強爲private fields,可能採取的格式爲
#foo
。在閉包中使用變量來表示私有值。
使用符號作爲屬性名稱,但這可能不能確保真正的隱私。
使用
WeakMap
來表示私有財產,如在另一個答案中所建議的。將您的對象包裝在
Proxy
中,如評論中所建議的那樣,它禁止訪問私有財產。
欲瞭解更多詳情和想法,請參閱this question。
代理聽起來像是一個非常糟糕的主意 - 它將如何知道允許或拒絕訪問? – Bergi
下面是一個使用封閉和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'))
請注意,ECMAScript 5中也可以這樣做,但除非實施了內存泄漏對該類使用'destroy()'方法,並在丟失對該對象實例的引用之前對其進行調用。 –
- 1. PHP動態對象屬性有沒有辦法讓它工作?
- 2. 有沒有辦法讓一個對象
- 3. 有沒有辦法讓一個按鈕屬於發件人對象的NSPanel?
- 4. 有沒有辦法讓Parse.com配置爲私人?
- 5. 私有對象屬性
- 6. 有沒有辦法鉤住對象屬性上的'刪除'?
- 7. 有沒有辦法控制JSON對象中的屬性順序?
- 8. jQuery.remove() - 刪除對象後,有沒有辦法讓對象返回?
- 9. 讓所有對象屬性
- 10. 有沒有辦法讓ngModel識別屬性綁定語法?
- 11. 有沒有辦法讓一個窗口的所有BindingExpression對象?
- 12. 有沒有辦法讓一個綁定的屬性DataContext
- 13. 有沒有辦法讓Rails的ActiveRecord屬性保密?
- 14. 'CheckoutView' 對象有沒有屬性 '對象'
- 15. 刪除對象的私有屬性
- 16. 有沒有辦法讓對講發言?
- 17. 私人對象沒有設置數據
- 18. 有沒有辦法讓Sublime Text 2自動完成HTML屬性?
- 19. 有沒有辦法讓console.table執行屬性存取函數?
- 20. jquery「對象沒有辦法」
- 21. 有什麼辦法可以防止替換JavaScript對象屬性?
- 22. 有沒有辦法讓saveAll()移除無關的對象?
- 23. 有沒有辦法讓一個可綁定的mxml對象?
- 24. 有沒有辦法引用自定義類對象的一個屬性/方法?
- 25. 有沒有辦法讓'this'屬性或'this other'屬性,但不是兩個?
- 26. 有沒有辦法刷新JavaScript中的窗口屬性?
- 27. 訪問私有對象屬性
- 28. 有沒有辦法在公共性狀中擁有私人功能?
- 29. Tastypie:讓「AttributeError的:‘NoneType’對象有沒有屬性'_clone」錯誤
- 30. 「remoteContext對象沒有屬性」
通過使用正常的類聲明,我不認爲這是可能的。但是聲明類的[**其他方式**](/ questions/5140833/privateness-in-javascript)。 –
什麼是應用程序?你可以使用'Proxy'。另請參閱https://stackoverflow.com/questions/40386767/how-to-create-static-array-in-javascript/ – guest271314