是否可以在ES6类中创建私有属性?
举个例子。 如何阻止访问instance.property?
class Something {
constructor(){
this.property = "test";
}
}
var instance = new Something();
console.log(instance.property); //=> "test"
是否可以在ES6类中创建私有属性?
举个例子。 如何阻止访问instance.property?
class Something {
constructor(){
this.property = "test";
}
}
var instance = new Something();
console.log(instance.property); //=> "test"
当前回答
class Something {
constructor(){
var _property = "test";
Object.defineProperty(this, "property", {
get: function(){ return _property}
});
}
}
var instance = new Something();
console.log(instance.property); //=> "test"
instance.property = "can read from outside, but can't write";
console.log(instance.property); //=> "test"
其他回答
使用WeakMap可以在类中拥有私有方法。
根据MDN网络文档:
WeakMap对象是键/值对的集合,其中键仅为对象,值可以是任意值。 键中的对象引用是弱保存的,这意味着如果不再有对该对象的其他引用,则它们是垃圾收集(GC)的目标。
这是一个创建带有私有成员_items的Queue数据结构的例子,该成员_items包含一个数组。
const _items = new WeakMap();
class Queue {
constructor() {
_items.set(this, []);
}
enqueue( item) {
_items.get(this).push(item);
}
get count() {
return _items.get(this).length;
}
peek() {
const anArray = _items.get(this);
if( anArray.length == 0)
throw new Error('There are no items in array!');
if( anArray.length > 0)
return anArray[0];
}
dequeue() {
const anArray = _items.get(this);
if( anArray.length == 0)
throw new Error('There are no items in array!');
if( anArray.length > 0)
return anArray.splice(0, 1)[0];
}
}
使用的例子:
const c = new Queue();
c.enqueue("one");
c.enqueue("two");
c.enqueue("three");
c.enqueue("four");
c.enqueue("five");
console.log(c);
私有成员_items是隐藏的,不能在Queue对象的属性或方法中看到:
然而,Queue对象中的私有成员_items可以通过以下方式访问:
const anArray = _items.get(this);
这取决于你问谁:-)
最大最小类提案中没有包含私有属性修饰符,这似乎已经进入了当前的草案。
但是,可能会支持私有名称,它允许私有属性—而且它们可能也可以用于类定义中。
现在大多数浏览器都支持私有类特性。
class Something {
#property;
constructor(){
this.#property = "test";
}
#privateMethod() {
return 'hello world';
}
getPrivateMessage() {
return this.#property;
}
}
const instance = new Something();
console.log(instance.property); //=> undefined
console.log(instance.privateMethod); //=> undefined
console.log(instance.getPrivateMessage()); //=> test
console.log(instance.#property); //=> Syntax error
更新:一个语法更好的提案正在酝酿中。欢迎投稿。
是的,对于对象的作用域访问,ES6引入了符号。
符号是唯一的,你不能从外部访问一个,除非通过反射(就像Java/ c#中的私有),但任何有权访问内部符号的人都可以使用它进行键访问:
var property = Symbol();
class Something {
constructor(){
this[property] = "test";
}
}
var instance = new Something();
console.log(instance.property); //=> undefined, can only access with access to the Symbol
答案是“不”。但是你可以像这样创建对属性的私有访问:
使用模块。模块中的所有内容都是私有的,除非使用export关键字将其设为公有。 在模块内部,使用函数闭包:http://www.kirupa.com/html5/closures_in_javascript.htm
(可以使用符号来确保隐私的建议在ES6规范的早期版本中是正确的,但现在不再是这样:https://mail.mozilla.org/pipermail/es-discuss/2014-January/035604.html和https://stackoverflow.com/a/22280202/1282216。有关符号和隐私的详细讨论,请参阅:https://curiosity-driven.org/private-properties-in-javascript)