是否可以在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"
当前回答
Yes totally can, and pretty easily too. This is done by exposing your private variables and functions by returning the prototype object graph in the constructor. This is nothing new, but take a bit of js foo to understand the elegance of it. This way does not use global scoped, or weakmaps. It is a form of reflection built into the language. Depending on how you leverage this; one can either force an exception which interrupts the call stack, or bury the exception as an undefined. This is demonstarted below, and can read more about these features here
class Clazz { constructor() { var _level = 1 function _private(x) { return _level * x; } return { level: _level, public: this.private, public2: function(x) { return _private(x); }, public3: function(x) { return _private(x) * this.public(x); }, }; } private(x) { return x * x; } } var clazz = new Clazz(); console.log(clazz._level); //undefined console.log(clazz._private); // undefined console.log(clazz.level); // 1 console.log(clazz.public(1)); //1 console.log(clazz.public2(2)); //2 console.log(clazz.public3(3)); //27 console.log(clazz.private(0)); //error
其他回答
你可以试试这个https://www.npmjs.com/package/private-members
这个包将按实例保存成员。
const pvt = require('private-members');
const _ = pvt();
let Exemplo = (function () {
function Exemplo() {
_(this).msg = "Minha Mensagem";
}
_().mensagem = function() {
return _(this).msg;
}
Exemplo.prototype.showMsg = function () {
let msg = _(this).mensagem();
console.log(msg);
};
return Exemplo;
})();
module.exports = Exemplo;
更新:一个语法更好的提案正在酝酿中。欢迎投稿。
是的,对于对象的作用域访问,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
我相信在构造函数中使用闭包是可能获得“两全其美”的。有两种变化:
所有数据成员都是私有的
函数myFunc() { console.log(' x的值:' + this.x); this.myPrivateFunc (); } 函数myPrivateFunc() { console.log(' x的增强值:' +(此。X + 1)); } 类测试{ 构造函数(){ Let internal = { X: 2, }; 内部的。myPrivateFunc = myPrivateFunc.bind(内部); 这一点。myFunc = myFunc.bind(内部); } };
有些成员是私有的
注意:这确实很难看。如果您知道更好的解决方案,请编辑此回复。
function myFunc(priv, pub) { pub.y = 3; // The Test object now gets a member 'y' with value 3. console.log('Value of x: ' + priv.x); this.myPrivateFunc(); } function myPrivateFunc() { pub.z = 5; // The Test object now gets a member 'z' with value 3. console.log('Enhanced value of x: ' + (priv.x + 1)); } class Test { constructor() { let self = this; let internal = { x : 2, }; internal.myPrivateFunc = myPrivateFunc.bind(null, internal, self); this.myFunc = myFunc.bind(null, internal, self); } };
在JS中获得真正隐私的唯一方法是通过作用域,因此不可能有一个属性是this的成员,只能在组件内部访问。在ES6中存储真正私有数据的最佳方法是使用WeakMap。
const privateProp1 = new WeakMap();
const privateProp2 = new WeakMap();
class SomeClass {
constructor() {
privateProp1.set(this, "I am Private1");
privateProp2.set(this, "I am Private2");
this.publicVar = "I am public";
this.publicMethod = () => {
console.log(privateProp1.get(this), privateProp2.get(this))
};
}
printPrivate() {
console.log(privateProp1.get(this));
}
}
显然,这可能是一个缓慢的,肯定是丑陋的,但它确实提供了隐私。
请记住,即使这样也不是完美的,因为Javascript是动态的。有人仍然可以这样做
var oldSet = WeakMap.prototype.set;
WeakMap.prototype.set = function(key, value){
// Store 'this', 'key', and 'value'
return oldSet.call(this, key, value);
};
为了在值被存储时捕获它们,所以如果你想格外小心的话,你需要捕获一个对.set和.get的本地引用来显式使用,而不是依赖于可覆盖的原型。
const {set: WMSet, get: WMGet} = WeakMap.prototype;
const privateProp1 = new WeakMap();
const privateProp2 = new WeakMap();
class SomeClass {
constructor() {
WMSet.call(privateProp1, this, "I am Private1");
WMSet.call(privateProp2, this, "I am Private2");
this.publicVar = "I am public";
this.publicMethod = () => {
console.log(WMGet.call(privateProp1, this), WMGet.call(privateProp2, this))
};
}
printPrivate() {
console.log(WMGet.call(privateProp1, this));
}
}
我已经开发了一个模块,帮助您使用的访问限制 JavaScript类,叫做Capsulable。(私有和受保护的静态)
如果您感兴趣,请查看下面的软件包。 https://github.com/hmmhmmhm/capsulable
const Capsulable = require('capsulable')
const Field = Capsulable()
class A {
constructor(_field){
// Configure data fields.
Field(this, _field)
// The code below provides access to
// the data fields when creating
// functions within the class.
Field(this).private
Field(this).protected
Field(this).protectedStatic
}
}
module.exports = A