91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在ES6中實現私有變量

發布時間:2021-06-04 17:30:16 來源:億速云 閱讀:171 作者:Leah 欄目:web開發

這期內容當中小編將會給大家帶來有關怎么在ES6中實現私有變量,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

1. 約定

實現

class Example {
  constructor() {
    this._private = 'private';
  }
  getName() {
    return this._private
  }
}

var ex = new Example();

console.log(ex.getName()); // private
console.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()); // private
console.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()); // private
console.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()); // private
console.log(ex.name); // undefined

優點

  • 無命名沖突

  • 外部無法訪問和修改

  • 無性能損失

缺點

  1. 寫法稍微復雜

  2. 兼容性也還好

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()); // private
console.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()); // private
console.log(ex.name); // undefined

優點

  • 無命名沖突

  • 外部無法訪問和修改

缺點

  • 寫法比較麻煩

  • 兼容性有點問題

  • 有一定性能代價

5. 最新提案

class Point {
 #x;
 #y;

 constructor(x, y) {
  this.#x = x;
  this.#y = y;
 }

 equals(point) {
  return this.#x === point.#x && this.#y === point.#y;
 }
}

那么為什么不直接使用 private 字段呢?比如說這樣:

class Foo {
 private value;

 equals(foo) {
  return this.value === foo.value;
 }
}

簡單點來說,就是嫌麻煩,當然也有性能上的考慮……

舉個例子,如果我們不使用 #,而是使用 private 關鍵字:

class Foo {
 private value = '1';

 equals(foo) {
  return this.value === foo.value;
 }
}

var foo1 = new Foo();
var foo2 = new Foo();

console.log(foo1.equals(foo2));

在這里我們新建了兩個實例,然后將 foo2 作為參數傳入了 foo1 的實例方法中。

那么我們可以獲取 foo2.value 的值嗎?如果我們直接 foo2.value 肯定是獲取不到值的,畢竟是私有變量,可是 equals 是 Foo 的一個類方法,那么可以獲取到的嗎?

答案是可以的。

其實這點在其他語言,比如說 Java 和 C++ 中也是一樣的,類的成員函數中可以訪問同類型實例的私有變量,這是因為私有是為了實現“對外”的信息隱藏,在類自己內部,沒有必要禁止私有變量的訪問,你也可以理解為私有變量的限制是以類為單位,而不是以對象為單位,此外這樣做也可以為使用者帶來便利。

既然獲取值是可以的,那么打印的結果應該為 true,但是如果我們傳入的值不是 Foo 的實例,而是一個其他對象呢?

var foo1 = new Foo();

console.log(foo1.equals({
 value: 2
}));

當然這里代碼也是可以正常運行的,但是對于編譯器來說,就有一點麻煩了,因為編譯器不知道 value 到底是 foo 的正常屬性還是私有屬性,所以編譯器需要做判斷,先判斷 foo 是不是 Foo 的實例,然后再接著獲取值。

這也意味著每次屬性訪問都需要做這樣一個判斷,而引擎已經圍繞屬性訪問做了高度優化,懶得改,而且還降低速度。

不過除了這個工作之外,還會有一些其他的內容需要考慮,比如說:

  • 你必須將私有的 key 編碼進每個詞法環境

  • for in 可以遍歷這些屬性嗎?

  • 私有屬性和正常屬性同名的時候,誰會屏蔽誰?

  • 怎么防止私有屬性的名稱不被探測出來。

關于使用 # 而不使用 private 更多的討論可以參考這個Issue。

當然這些問題都可以被解決啦,就是麻煩了點。

而如果你選擇 #,實現的方式將跟 JavaScript 對象屬性完全沒有關系,將會使用 private slots 的方式以及使用一個新的 slot 查找語法,總之就是會比 private 的實現方式簡單很多。

上述就是小編為大家分享的怎么在ES6中實現私有變量了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

es6
AI

蕉岭县| 江阴市| 鸡泽县| 麻栗坡县| 星子县| 湖北省| 长宁县| 山西省| 瓮安县| 陆良县| 潍坊市| 隆安县| 绥滨县| 玛曲县| 聂拉木县| 龙山县| 苏尼特右旗| 五华县| 新乐市| 郯城县| 五寨县| 治县。| 金平| 清流县| 徐闻县| 平罗县| 翁牛特旗| 永丰县| 泸州市| 陆良县| 固原市| 富锦市| 合肥市| 淅川县| 博白县| 玉林市| 电白县| 无为县| 开化县| 东港市| 泾阳县|