亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

詳解ES6系列之私有變量的實現

2024-05-06 16:46:54
字體:
來源:轉載
供稿:網友

前言

在閱讀 《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

優點

  • 無命名沖突
  • 外部無法訪問和修改
  • 無性能損失

缺點

  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()); // 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

優點

  • 無命名沖突
  • 外部無法訪問和修改

缺點

  • 寫法比較麻煩
  • 兼容性有點問題
  • 有一定性能代價

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 的實現方式簡單很多。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲黄色成人网| 成人av.网址在线网站| 亚洲人成绝费网站色www| 日本高清不卡的在线| 午夜精品福利电影| 国产欧美va欧美va香蕉在| 福利二区91精品bt7086| 欧美激情网站在线观看| 亚洲精品日韩久久久| 久久精品中文字幕免费mv| 亚洲japanese制服美女| 欧美精品在线免费| 欧美成人中文字幕在线| 国产亚洲激情视频在线| 亚洲欧美成人一区二区在线电影| 欧美黄色片视频| 国产精品永久在线| 国产成人一区二| 久久精品国产2020观看福利| 国产视频在线观看一区二区| 国产视频久久久久久久| 亚洲天堂网在线观看| 欧美性受xxxx白人性爽| 91久久中文字幕| 亚洲精品动漫久久久久| 欧美激情国产高清| xxx成人少妇69| 超碰97人人做人人爱少妇| 成人网中文字幕| 国产最新精品视频| 一本色道久久综合狠狠躁篇的优点| 国产精品久久久| 精品网站999www| 国产精品入口夜色视频大尺度| 狠狠色狠色综合曰曰| 国产精品色婷婷视频| 日韩福利伦理影院免费| 欧美激情在线一区| 性色av一区二区三区免费| 日韩电影中文 亚洲精品乱码| 亚洲自拍欧美色图| 自拍偷拍亚洲一区| 日韩av手机在线| 国产欧美日韩精品专区| 45www国产精品网站| 欧美精品久久久久久久久久| 91视频-88av| 国产欧美日韩最新| 欧美成人精品在线观看| 国产精品av网站| 九九热这里只有在线精品视| 成人在线中文字幕| 91九色国产社区在线观看| 国产精品久久网| 久久天天躁狠狠躁夜夜爽蜜月| 欧美伊久线香蕉线新在线| 超碰91人人草人人干| 亚洲无线码在线一区观看| 国外日韩电影在线观看| 国产成人97精品免费看片| 国产欧美va欧美va香蕉在线| 色偷偷av一区二区三区乱| 国产精品亚洲аv天堂网| 亚洲欧美一区二区三区在线| 亚洲黄色片网站| 亚洲天堂网在线观看| 青青草原成人在线视频| 最近2019好看的中文字幕免费| 日韩精品视频中文在线观看| 国产精品自拍视频| 狠狠躁夜夜躁人人躁婷婷91| 日韩av在线天堂网| 国产一区二区三区欧美| 欧洲亚洲女同hd| 亚洲最大的网站| 久久久久久久91| 日韩精品在线免费观看| 国产精品嫩草视频| 4444欧美成人kkkk| 久久成人18免费网站| 4k岛国日韩精品**专区| 91亚洲精华国产精华| 国产午夜精品美女视频明星a级| 精品激情国产视频| 色综合久久悠悠| 国产精品无av码在线观看| 色视频www在线播放国产成人| 久久99国产精品自在自在app| 欧美日韩一区二区精品| 日韩av在线精品| 精品国产一区二区三区久久| 69国产精品成人在线播放| 色777狠狠综合秋免鲁丝| 亚洲国产小视频| 国产视频精品xxxx| 伊人伊成久久人综合网站| 久久免费少妇高潮久久精品99| 欧美国产中文字幕| 欧美日韩国产精品| 日韩激情av在线免费观看| 亚洲国产天堂久久综合网| 国产精品久久久久影院日本| 91亚洲一区精品| 亚洲女在线观看| 亚洲影影院av| 欧美性猛交99久久久久99按摩| 情事1991在线| 亚洲视频第一页| 欧美成人免费全部观看天天性色| 久久免费观看视频| 欧美专区福利在线| 亚洲日本中文字幕免费在线不卡| 91精品国产电影| 国产精品视频xxx| 欧美激情综合亚洲一二区| 欧美大码xxxx| 91中文在线观看| 亚洲视频日韩精品| 欧美激情一区二区三级高清视频| 日韩黄在线观看| 亚洲欧美激情精品一区二区| 成人国产精品色哟哟| 日韩综合中文字幕| 国产精品成人品| 久久久国产成人精品| 亚洲奶大毛多的老太婆| 久久露脸国产精品| 国产精品视频久久久久| 欧美床上激情在线观看| 操人视频在线观看欧美| 久久久久久97| 日韩精品久久久久久久玫瑰园| 欧美一区二区三区精品电影| 在线亚洲国产精品网| 26uuu另类亚洲欧美日本老年| 欧美性xxxxxxxxx| 97在线免费观看| 亚洲第一偷拍网| 成人综合网网址| 国产成人在线亚洲欧美| 91精品国产沙发| 欧美人与物videos| 国内精品久久久久久影视8| 日韩女优人人人人射在线视频| 欧美孕妇孕交黑巨大网站| 欧美福利小视频| 日韩美女视频免费看| 51色欧美片视频在线观看| 欧美劲爆第一页| 国产精品永久在线| 中文字幕一区二区三区电影| 久久久久久网站| 久久伊人91精品综合网站| 亚洲奶大毛多的老太婆| 亚洲国产精彩中文乱码av| 久久在线精品视频| 在线视频免费一区二区| 51色欧美片视频在线观看| 久久久www成人免费精品张筱雨| 精品免费在线视频| 在线观看日韩www视频免费| 欧美国产日韩一区二区在线观看| 欧美性xxxxxxxxx| 亚洲成人国产精品|