前言
在閱讀 《ECMAScript 6 入門》的時候,零散的看到有私有變量的實現,所以在此總結一篇。
1. 約定
實現
class Example { constructor() { this._private = 'private'; } getName() { return this._private }}var ex = new Example();console.log(ex.getName()); // privateconsole.log(ex._private); // private優點
寫法簡單 調試方便 兼容性好缺點
外部可以訪問和修改 語言沒有配合的機制,如 for in 語句會將所有屬性枚舉出來 命名沖突2. 閉包
實現一
/** * 實現一 */class Example { constructor() { var _private = ''; _private = 'private'; this.getName = function() {return _private} }}var ex = new Example();console.log(ex.getName()); // privateconsole.log(ex._private); // undefined優點
無命名沖突 外部無法訪問和修改缺點
constructor 的邏輯變得復雜。構造函數應該只做對象初始化的事情,現在為了實現私有變量,必須包含部分方法的實現,代碼組織上略不清晰。 方法存在于實例,而非原型上,子類也無法使用 super 調用 構建增加一點點開銷實現二
/** * 實現二 */const Example = (function() { var _private = ''; class Example { constructor() { _private = 'private'; } getName() { return _private; } } return Example;})();var ex = new Example();console.log(ex.getName()); // privateconsole.log(ex._private); // undefined優點
無命名沖突 外部無法訪問和修改缺點
寫法有一點復雜 構建增加一點點開銷3. Symbol
實現
const Example = (function() { var _private = Symbol('private'); class Example { constructor() { this[_private] = 'private'; } getName() { return this[_private]; } } return Example;})();var ex = new Example();console.log(ex.getName()); // privateconsole.log(ex.name); // undefined優點
無命名沖突 外部無法訪問和修改 無性能損失缺點
4. WeakMap
實現
/** * 實現一 */const _private = new WeakMap();class Example { constructor() { _private.set(this, 'private'); } getName() { return _private.get(this); }}var ex = new Example();console.log(ex.getName()); // privateconsole.log(ex.name); // undefined如果這樣寫,你可能覺得封裝性不夠,你也可以這樣寫:
/** * 實現二 */const Example = (function() { var _private = new WeakMap(); // 私有成員存儲容器 class Example { constructor() { _private.set(this, 'private'); } getName() { return _private.get(this); } } return Example;})();var ex = new Example();console.log(ex.getName()); // privateconsole.log(ex.name); // undefined
新聞熱點
疑難解答
圖片精選