真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

ES6中私有變量怎么弄

小編給大家分享一下ES6中私有變量怎么弄,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供辛集網(wǎng)站建設(shè)、辛集做網(wǎng)站、辛集網(wǎng)站設(shè)計、辛集網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、辛集企業(yè)網(wǎng)站模板建站服務(wù),十載辛集做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。

1. 約定

實現(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)點

  1. 寫法簡單

  2. 調(diào)試方便

  3. 兼容性好

缺點

  1. 外部可以訪問和修改

  2. 語言沒有配合的機制,如 for in 語句會將所有屬性枚舉出來

  3. 命名沖突

2. 閉包

實現(xiàn)一

/**
 * 實現(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)點

  1. 無命名沖突

  2. 外部無法訪問和修改

缺點

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

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

  3. 構(gòu)建增加一點點開銷

實現(xiàn)二

/**
 * 實現(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)點

  1. 無命名沖突

  2. 外部無法訪問和修改

缺點

  1. 寫法有一點復(fù)雜

  2. 構(gòu)建增加一點點開銷

3. Symbol

實現(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)點

  1. 無命名沖突

  2. 外部無法訪問和修改

  3. 無性能損失

缺點

  1. 寫法稍微復(fù)雜

  2. 兼容性也還好

4. WeakMap

實現(xiàn)

/**
 * 實現(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

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

/**
 * 實現(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)點

  1. 無命名沖突

  2. 外部無法訪問和修改

缺點

  1. 寫法比較麻煩

  2. 兼容性有點問題

  3. 有一定性能代價

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

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

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

答案是可以的。

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

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

var foo1 = new Foo();

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

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

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

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

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

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

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

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

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

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

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

以上是ES6中私有變量怎么弄的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!


網(wǎng)站標題:ES6中私有變量怎么弄
新聞來源:http://weahome.cn/article/ggodge.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部