是否可以在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"
当前回答
这里,myThing变量是私有的,是闭包的一部分:
class Person {
constructor() {
var myThing = "Hello World";
return {
thing: myThing,
sayThing: this.sayThing
}
}
sayThing() {
console.log(this.thing);
}
}
var person = new Person();
console.log(person);
其他回答
我有一个解决办法,它很简单…虽然性能不是问题…但它确实有效,而且效果很好。
诀窍在于,在私有属性和函数被建立和标准化/采用之前,需要另一种解决方案,这是另一种解决方案…
class ClassPrivateProperties {
constructor(instance) {
const $this = instance;
let properties = {};
this.prop = (key, value = undefined) => {
if (!value) {
return properties[key];
} else {
properties[key] = value;
}
};
this.clear = instance => {
if ($this === instance) {
properties = {};
return true;
} else {
return false;
}
}
}
}
这是一个示例用法,可以是什么(如果你使用上面的感觉自由,使它更好)
class Test {
constructor() {
this._privateProps = new ClassPrivateProperties(this);
}
property(key, value = undefined) {
if (!value) {
return this._privateProps.prop(key);
} else {
this._privateProps.prop(key, value);
}
}
clear() { return this._privateProps.clear(this); }
}
const test = new test;
test.property('myKey','some value here');
console.log(test.property('myKey'));
就像我提到的,这个问题不是最好的,但它工作,使属性真正的私有。
来这个派对很晚,但我在搜索中碰到了OP问题,所以… 是的,您可以通过将类声明包装在闭包中来拥有私有属性
这里有一个我如何在这个代码依赖中拥有私有方法的例子。在下面的代码片段中,Subscribable类有两个“私有”函数process和processCallbacks。任何属性都可以以这种方式添加,并且通过使用闭包将它们保持为私有。如果关注点被很好地分离,并且Javascript不需要通过添加更多的语法而变得臃肿,当闭包整齐地完成工作时,隐私是一个罕见的需求。
const Subscribable = (function(){
const process = (self, eventName, args) => {
self.processing.set(eventName, setTimeout(() => processCallbacks(self, eventName, args)))};
const processCallbacks = (self, eventName, args) => {
if (self.callingBack.get(eventName).length > 0){
const [nextCallback, ...callingBack] = self.callingBack.get(eventName);
self.callingBack.set(eventName, callingBack);
process(self, eventName, args);
nextCallback(...args)}
else {
delete self.processing.delete(eventName)}};
return class {
constructor(){
this.callingBack = new Map();
this.processing = new Map();
this.toCallbacks = new Map()}
subscribe(eventName, callback){
const callbacks = this.unsubscribe(eventName, callback);
this.toCallbacks.set(eventName, [...callbacks, callback]);
return () => this.unsubscribe(eventName, callback)} // callable to unsubscribe for convenience
unsubscribe(eventName, callback){
let callbacks = this.toCallbacks.get(eventName) || [];
callbacks = callbacks.filter(subscribedCallback => subscribedCallback !== callback);
if (callbacks.length > 0) {
this.toCallbacks.set(eventName, callbacks)}
else {
this.toCallbacks.delete(eventName)}
return callbacks}
emit(eventName, ...args){
this.callingBack.set(eventName, this.toCallbacks.get(eventName) || []);
if (!this.processing.has(eventName)){
process(this, eventName, args)}}}})();
我喜欢这种方法,因为它很好地分离了关注点,并保持了真正的私密性。唯一的缺点是需要使用'self'(或类似的东西)在私有内容中引用'this'。
这取决于你问谁:-)
最大最小类提案中没有包含私有属性修饰符,这似乎已经进入了当前的草案。
但是,可能会支持私有名称,它允许私有属性—而且它们可能也可以用于类定义中。
我找到了一个非常简单的解决方案,只需使用Object.freeze()。当然,问题是以后你不能向对象添加任何东西。
class Cat {
constructor(name ,age) {
this.name = name
this.age = age
Object.freeze(this)
}
}
let cat = new Cat('Garfield', 5)
cat.age = 6 // doesn't work, even throws an error in strict mode
甚至Typescript也做不到。从他们的文档来看:
当成员被标记为private时,就不能从其包含类的外部访问它。例如: 动物类{ 私有名称:字符串; 构造函数(名称:字符串){this.name =名称;} } 新的动物(猫). name;//错误:'name'是private;
但在他们的操场上,这说明:
var Animal = (function () {
function Animal(theName) {
this.name = theName;
}
return Animal;
}());
console.log(new Animal("Cat").name);
所以他们的“私人”关键字是无效的。