2015-07-21 164 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