2015-07-21 92 views
2

如何使用ES6类创建私有变量和方法,该类应该可以通过同一类的公共方法访问。如何在ES6类中创建私有变量和方法?

class MyClass { 
    constructor() { 
     this.publicVar = "I am public"; 
     //some private Variable e.g privteVar1 = "I am Private1"; privateVar2 = "I am Private2"; 
     this.publicMethod =() => { 
     //it should have accesses to private variables and methods 
      console.log(privateVar1, privateVar2) 
     }; 
     //similarly need to create some privateMethod   
    } 

    render() { 
     //it also should have access to the private variables 
    } 

} 
+0

我查了一样。但不清楚。如果有人在我给出的这个特定例子中帮助我,那将会很棒。 – jrath

+0

完全和以前一样。或者使用链接问题中建议的内容。另请参阅http://stackoverflow.com/q/30191656/218196 –

回答

-4

试试这个:

console.log(this[privateVar1], this[privateVar2]) 

打电话给你的这类似[myPrivate。这是让您的物业成为某种私人物品的方式。但是这种语法不能提供真正的隐私。

1

只是使它成为当地变量,与var/let/const,这将可通过关闭所有你在构造函数中定义的特权方法。这从ES5没有改变,顺便说一句。

class MyClass { 
    constructor() { 
     this.publicVar = "I am public"; 
     const privteVar1 = "I am Private1", 
     const privateVar2 = "I am Private2"; 
     this.publicMethod =() => { 
      // it has access to private variables 
      console.log(privateVar1, privateVar2) 
     };   
    } 
} 

注意,这些变量是局部的构造函数,所以你不能从你的原型方法来访问他们,对于那些你需要的公共属性或复杂的解决方法。

+0

如果我需要在构造函数()之外访问privateVar,那么在同一类的其他方法中如何访问呢?在这种情况下,privateVar是未定义的。 – jrath

+0

请参考我编辑的问题,我在构造函数外添加了render()。还有我需要访问私有变量。 – jrath

+0

@jrath:'render'是一个原型方法,我已经评论过这些。在构造函数中移动它,或从变量切换到公共属性。 – Bergi

0

在JS中获得真实隐私的唯一方法是通过范围确定,因此无法拥有属于仅可在组件内部访问的this成员的属性。在ES6中存储真正的私人数据的最佳方式是使用WeakMap。

const privateProp1 = new WeakMap(); 
const privateProp2 = new WeakMap(); 

class MyClass { 
    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)) 
    };   
    } 

    render() { 
    //it also should have access to the private variables 
    console.log(privateProp1.get(this)); 
    } 

} 
+0

我没有说这是完美的,但在我看来,这是获得真实隐私而不会在其他地方产生费用的唯一方法。在构造函数中捕获变量是有效的,但是你有创建新函数表达式的前期成本,并且你失去了类语法的许多好处。 – loganfsmyth

+0

哦,算了吧。我读过的一个地方是,weakmaps会导致deoptimisation,并在垃圾收集器上产生额外的,意想不到的成本,但我再也找不到那个参考,我必须误解这一点。现在我唯一的厌恶就是他们丑陋的语法: -/ – Bergi

+0

不能在那里争论,哈哈。 – loganfsmyth

1

您可以使用Symbol来实现这样的:

var privateSymbol = Symbol('private'); 

class SomeClass { 
    constructor() { 
    this.setPrivateValue('some init value'); 
    } 

    setPrivateValue(value) { 
    this[privateSymbol] = value; 
    } 

    getPrivateValue() { 
    return this[privateValue]; 
    } 
} 

注意把以前的代码在某些模块,不要暴露privateSymbol

2

正如@yibuyisheng所注意的那样,您可以使用符号来创建对属性的不可访问引用。你也可以创建私有方法。

var privateMethod = Symbol('private'); 

class SomeClass { 
    constructor() { 
    } 

    [privateMethod]() { 
    // some private actions 
    } 

    render() { 
    // call private method 
    this[privateMethod]() 
    } 
} 

符号创建一个唯一的引用,它可以用作属性名称。这个属性或方法只能通过使用它来调用。这是可能的,因为ES6引入了computed properties syntax,您可以使用变量来定义动态属性。

如果您未将此符号公开给其他人,只有您可以称其为符号。

+0

编号符号键是公开的,就像字符串属性名称一样,并且可以被枚举。你不能隐藏它们。 – Bergi

+0

没有。类方法不能按spec来迭代。请参阅babel-repl示例:http://bit.ly/1SCI5rD –

+0

我并不是说他们可以用'for in'循环枚举(没有方法,您不需要这样的符号)。我说[符号与普通属性一样暴露](https://babeljs.io/repl/#?evaluate=true&code=var%20privateMethod%20%3D%20Symbol('private')%3B%0A%0Aclass %20SomeClass%20%7B%0A%20%20%5BprivateMethod%5D()%20%7B%0A%20%20%20%20%2F%2F%20some%20private%20actions%0A%20%20%7D %0A%7D%0A%0Avar%20keys%20%3D%20Reflect.ownKeys(SomeClass.prototype)%0Aconsole.log( '访问%20keys' %2C%20keys)%3B%0Aconsole.log('%22private%22 %20方法%3A'%2C%20(新%20SomeClass)%5Bkeys%5B1%5D%5D)) – Bergi