成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

ES6 系列之私有變量的實(shí)現(xiàn)

lentoo / 1379人閱讀

摘要:前言在閱讀入門的時候,零散的看到有私有變量的實(shí)現(xiàn),所以在此總結(jié)一篇。構(gòu)造函數(shù)應(yīng)該只做對象初始化的事情,現(xiàn)在為了實(shí)現(xiàn)私有變量,必須包含部分方法的實(shí)現(xiàn),代碼組織上略不清晰。

前言

在閱讀 《ECMAScript 6 入門》的時候,零散的看到有私有變量的實(shí)現(xiàn),所以在此總結(jié)一篇。

1. 約定 實(shí)現(xiàn)
class Example {
    constructor() {
        this._private = "private";
    }
    getName() {
        return this._private
    }
}

var ex = new Example();

console.log(ex.getName()); // private
console.log(ex._private); // private
優(yōu)點(diǎn)

寫法簡單

調(diào)試方便

兼容性好

缺點(diǎn)

外部可以訪問和修改

語言沒有配合的機(jī)制,如 for in 語句會將所有屬性枚舉出來

命名沖突

2. 閉包 實(shí)現(xiàn)一
/**
 * 實(shí)現(xiàn)一
 */
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
優(yōu)點(diǎn)

無命名沖突

外部無法訪問和修改

缺點(diǎn)

constructor 的邏輯變得復(fù)雜。構(gòu)造函數(shù)應(yīng)該只做對象初始化的事情,現(xiàn)在為了實(shí)現(xiàn)私有變量,必須包含部分方法的實(shí)現(xiàn),代碼組織上略不清晰。

方法存在于實(shí)例,而非原型上,子類也無法使用 super 調(diào)用

構(gòu)建增加一點(diǎn)點(diǎn)開銷

實(shí)現(xiàn)二
/**
 * 實(shí)現(xiàn)二
 */
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
優(yōu)點(diǎn)

無命名沖突

外部無法訪問和修改

缺點(diǎn)

寫法有一點(diǎn)復(fù)雜

構(gòu)建增加一點(diǎn)點(diǎn)開銷

3. Symbol 實(shí)現(xiàn)
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
優(yōu)點(diǎn)

無命名沖突

外部無法訪問和修改

無性能損失

缺點(diǎn)

寫法稍微復(fù)雜

兼容性也還好

4. WeakMap 實(shí)現(xiàn)
/**
 * 實(shí)現(xiàn)一
 */
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

如果這樣寫,你可能覺得封裝性不夠,你也可以這樣寫:

/**
 * 實(shí)現(xiàn)二
 */
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
優(yōu)點(diǎn)

無命名沖突

外部無法訪問和修改

缺點(diǎn)

寫法比較麻煩

兼容性有點(diǎn)問題

有一定性能代價

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;
  }
}

簡單點(diǎn)來說,就是嫌麻煩,當(dāng)然也有性能上的考慮……

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

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

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

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

答案是可以的。

其實(shí)這點(diǎn)在其他語言,比如說 Java 和 C++ 中也是一樣的,類的成員函數(shù)中可以訪問同類型實(shí)例的私有變量,這是因?yàn)樗接惺菫榱藢?shí)現(xiàn)“對外”的信息隱藏,在類自己內(nèi)部,沒有必要禁止私有變量的訪問,你也可以理解為私有變量的限制是以類為單位,而不是以對象為單位,此外這樣做也可以為使用者帶來便利。

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

var foo1 = new Foo();

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

當(dāng)然這里代碼也是可以正常運(yùn)行的,但是對于編譯器來說,就有一點(diǎn)麻煩了,因?yàn)榫幾g器不知道 value 到底是 foo 的正常屬性還是私有屬性,所以編譯器需要做判斷,先判斷 foo 是不是 Foo 的實(shí)例,然后再接著獲取值。

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

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

你必須將私有的 key 編碼進(jìn)每個詞法環(huán)境

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

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

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

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

當(dāng)然這些問題都可以被解決啦,就是麻煩了點(diǎn)。

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

參考

《編程語言如何演化——以JS的private為例》賀師俊

Exploring ES6

譯 JS 新語法:私有屬性

ES6 系列

ES6 系列目錄地址:https://github.com/mqyqingfeng/Blog

ES6 系列預(yù)計(jì)寫二十篇左右,旨在加深 ES6 部分知識點(diǎn)的理解,重點(diǎn)講解塊級作用域、標(biāo)簽?zāi)0?、箭頭函數(shù)、Symbol、Set、Map 以及 Promise 的模擬實(shí)現(xiàn)、模塊加載方案、異步處理等內(nèi)容。

如果有錯誤或者不嚴(yán)謹(jǐn)?shù)牡胤?,請?wù)必給予指正,十分感謝。如果喜歡或者有所啟發(fā),歡迎 star,對作者也是一種鼓勵。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/108767.html

相關(guān)文章

  • ES6 系列 WeakMap

    摘要:一個對象若只被弱引用所引用,則被認(rèn)為是不可訪問或弱可訪問的,并因此可能在任何時刻被回收。也就是說,一旦不再需要,里面的鍵名對象和所對應(yīng)的鍵值對會自動消失,不用手動刪除引用。如果有錯誤或者不嚴(yán)謹(jǐn)?shù)牡胤?,請?wù)必給予指正,十分感謝。 前言 我們先從 WeakMap 的特性說起,然后聊聊 WeakMap 的一些應(yīng)用場景。 特性 1. WeakMap 只接受對象作為鍵名 const map = ...

    CollinPeng 評論0 收藏0
  • ES6模塊詳解

    摘要:例如我們導(dǎo)入模塊,可以這么導(dǎo)入桃翁歡迎關(guān)注公眾號前端桃園報(bào)錯不能定義相同名字變量報(bào)錯,不能重新賦值小豬可以看到導(dǎo)入綁定這里不理解綁定,文章后面會解釋時,形式類似于對象解構(gòu),但實(shí)際上并無關(guān)聯(lián)。 歡迎訪問個人站點(diǎn) 簡介 何為模塊 一個模塊只不過是一個寫在文件中的 JavaScript 代碼塊。 模塊中的函數(shù)或變量不可用,除非模塊文件導(dǎo)出它們。 簡單地說,這些模塊可以幫助你在你的模塊中編寫...

    huashiou 評論0 收藏0
  • ES6 完全使用手冊

    摘要:前言這里的泛指之后的新語法這里的完全是指本文會不斷更新這里的使用是指本文會展示很多的使用場景這里的手冊是指你可以參照本文將項(xiàng)目更多的重構(gòu)為語法此外還要注意這里不一定就是正式進(jìn)入規(guī)范的語法。 前言 這里的 ES6 泛指 ES5 之后的新語法 這里的 完全 是指本文會不斷更新 這里的 使用 是指本文會展示很多 ES6 的使用場景 這里的 手冊 是指你可以參照本文將項(xiàng)目更多的重構(gòu)為 ES6...

    kgbook 評論0 收藏0
  • JavaScript 是如何工作:模塊構(gòu)建以及對應(yīng)打包工具

    摘要:掛機(jī)科了次使用這個結(jié)構(gòu),匿名函數(shù)就有了自己的執(zhí)行環(huán)境或閉包,然后我們立即執(zhí)行。注意,匿名函數(shù)的圓括號是必需的,因?yàn)橐躁P(guān)鍵字開頭的語句通常被認(rèn)為是函數(shù)聲明請記住,中不能使用未命名的函數(shù)聲明。 這是專門探索 JavaScript 及其所構(gòu)建的組件的系列文章的第 20 篇。 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! 如果你錯過了前面的章節(jié),可以在這里找到它們: ...

    hedzr 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<