ECMA Script 6_Symbol() 惟一類型值聲明函數_Symbol 數據類型

Symbol 數據類型函數

  • let s = Symbol();
    
    typeof s;    // "symbol"

是 ES6 繼 Number,String,Boolean,Undefined,Null 以後引入的新數據類型spa

對象的屬性名如今能夠有兩種類型,一種是原來就有的字符串,另外一種就是新增的 Symbol 類型設計

Symbol 函數的參數只是表示對當前 Symbol 值的描述code

  • let s1 = Symbol('foo');
    let s2 = Symbol('bar');
    
    s1     // Symbol(foo)
    s2     // Symbol(bar)
    
    s1.toString();     // "Symbol(foo)"
    s2.toString();     // "Symbol(bar)"

凡是屬性名屬於 Symbol 類型,就都是獨一無二的,能夠保證不會與其餘屬性名產生衝突對象

背景:blog

ES5 的對象屬性名都是字符串,這容易形成屬性名的衝突ip

若是有一種機制,保證每一個屬性的名字都是獨一無二的就行了,這樣就從根本上防止屬性名的衝突。字符串

  • 原始數據類型 Symbol

表示獨一無二的值。get

它是 JavaScript 語言的第七種數據類型iframe

Symbol 值能夠顯式轉爲字符串

Symbol 值能夠顯式轉爲布爾值

  • Symbol 值不能與其餘類型的值進行運算,會報錯
  • 即便 Symbol 函數參數相同,可是它們是不相等的。
  • Symbol 值 做爲對象的屬性時,只能用 [ ] 訪問進行讀寫

在對象的內部,使用 Symbol 值定義屬性時,Symbol 值必須放在方括號之中

  • let s = Symbol();  let obj = { [s]: function (arg) { ... } }; obj[s](123);
  • 常量使用 Symbol 值最大的好處,就是其餘任何值都不可能有相同的值了,所以能夠保證上面的switch語句會按設計的方式工做
  • const COLOR_RED    = Symbol();
    const COLOR_GREEN  = Symbol();
    
    function getComplement(color) {
        switch (color) {
            case COLOR_RED:
                return COLOR_N:
                return COLOR_GREEN;
            case COLOR_GREERED;
            default:
                throw new Error('Undefined color');
        };
    };
  • 消除魔術字符串的方法,就是把它寫成一個變量
  • const shapeType = {
        triangle: Symbol(),
    };
    
    function getArea(shape, options) {
        let area = 0;
        switch (shape) {
            case shapeType.triangle:
                area = .5 * options.width * options.height;
                break;
        };
        return area;
    };
    
    getArea(shapeType.triangle, { width: 100, height: 100 });
  • Symbol 做爲屬性時,非私有屬性,遍歷法
  • Symbol 做爲屬性名,該屬性不會出如今for...infor...of循環中,也不會被Object.keys()Object.getOwnPropertyNames()JSON.stringify()返回
  • 可是,它也不是私有屬性,有一個 Object.getOwnPropertySymbols() 獲取指定對象的全部 Symbol 屬性名
  • 從新使用同一個 Symbol 值,Symbol.for('aName')

接受一個字符串做爲參數,而後搜索有沒有以該參數做爲名稱的 Symbol 值。

  • 若是有,就返回這個 Symbol 值
  • 不然就新建並返回一個以該字符串爲名稱的 Symbol 值
  • let s1 = Symbol.for('foo');    // 登記在全局環境中供搜索
    let s2 = Symbol.for('foo');    // 登記在全局環境中供搜索
    
    s1 === s2 // true

Symbol.for()Symbol()這兩種寫法,都會生成新的 Symbol。

它們的區別是:

前者會被登記在全局環境中供搜索,後者不會。

Symbol.for()不會每次調用就返回一個新的 Symbol 類型的值,而是會先檢查給定的key是否已經存在,若是不存在纔會新建一個值。

好比,若是你調用Symbol.for("cat")30 次,每次都會返回同一個 Symbol 值,

可是調用Symbol("cat")30 次,會返回 30 個不一樣的 Symbol 值

  • Symbol.keyFor() 返回一個已登記的 Symbol 類型值的 key,即 Symbol.for() 生成的 Symbol 值
  • 注意: 爲 Symbol 值登記的名字,是全局環境的,能夠在不一樣的 iframe 或 service worker 中取到同一個值
  •  
    let obj = {
        [Symbol('my_key')]: 1,
        enum: 2,
        nonEnum: 3
    };
    
    Reflect.ownKeys(obj);    //  ["enum", "nonEnum", Symbol(my_key)]
相關文章
相關標籤/搜索