ES6符號(Symbol)學習總結

==========================普通符號=======================
    符號是ES6新增的一個數據類型, 它使用函數  Symbol(符號描述) 來創建
       // 創建要給符號
        const syb1 = Symbol();
        const syb2 = Symbol("abc");
        console.log(syb1, syb1) // Symbol()  Symbol(abc)
    設置符號的初衷,是爲了給對象設置私有屬性  
    
    在以前對象不想給人家用的屬性,類似: __prop__等
    私有屬性: 只能在對象內部使用,外部無法使用

    符號的特點:
     1. 符號沒有字面量
     2. 使用typeof() 得到的是symbol
     3. 每一次調用Symbol函數得到的符號永遠不相等,無論符號是否相同
      3-1. 符號可以作爲對象的屬性名存在,這種屬性稱爲符號屬性
        例如:
        const sy = Symbol("符號屬性");
        const user = {
            a: 1,
            b: 2,
            [sy]: '私有屬性,外部訪問不了' 
        };

        3-2. 開發者可以通過精心的設計,使得返回的屬性外部無法訪問:
        列如:上面的 user[sy] // 報錯

       3-3. 符號屬性是無法枚舉的,因此在for-in循環中無法讀取到符號屬性,Object.keys也無法讀取到符號的屬性
       const syb = Symbol();
        const obj = {
            [syb]: "",
            a: 1,
            b: 2
        }
        for (const key in object) {
            if (object.hasOwnProperty(key)) {
                const element = object[key];
                // 無法獲取到syb
            }
        }

        3-4. Object.getOwnPropertyNames 儘管可以得到所有無法枚舉的屬性,但是仍然無法讀取到符號屬性

        3-5 es6 新增 Object.getOwnPropertySymbols 來獲取符號屬性

      4. 符號無法隱式轉換, 因此不能用於數學運算,字符串的拼接或其他隱式轉換的場景,但是符號可以顯示的轉換爲字符串,
      通過String 構造函數進行轉換即可, console.log() 之所以可以打印符號,是他的內部進行了顯式轉換 


      ==========================共享符號============================
      根據某個符號名稱(符號描述)能夠得到同一個符號;
      例如:
       const syb = Symbol();
        const obj1 = {
            a: 1,
            b: 2,
            [syb]: 3,
        }

        const obj2 = {
            [syb]: "c",
            a: 2
        }

        // 代碼在 同一模塊以上的方法式可以的,但是如果代碼不在同一模塊,那就可以使用共享符號

        共享符號語法:
        Symbol.for("符號名/符號描述") // 獲取共享符號
        
      const syb1 = Symbol.for();
       const syb2 = Symbol.for();
       console.log(syb1 === syb2)//true 會發現兩個符號相同的了

       const syb1 = Symbol.for("abc");
       const syb2 = Symbol.for("abc");
       console.log(syb1 === syb2)//true 會發現兩個符號相同的了

      const syb = Symbol.for("abc");
       const obj = {
           a: 123,
           [ Symbol.for("abc")]: b,
       }
       // 外部可以使用以下的方法進行訪問
       console.log(obj.[Symbol.for("abc")]) // b 可以獲取到

       // 共享符合的實現原理
         const SymbolFor = (() => {
                const global = {}; // 用於記錄有哪些共享符號
                return function (name) {
                    if (!global[name]) {
                        global[name] = Symbol(name);
                    }
                    return global[name];
                }
            })()


           ==============知名(公共, 具名)符號=======================
           知名符號是一些具有特殊含義的共享符號,通過 Symbol的靜態屬性得到
            ES6 延續了 ES5 的思想: 減少魔法, 暴露內部實現!
            因此, ES6 用知名符號暴露了某些場景的內部實現

            1. Symbol.hasInstance 該符號用於定義構造函數的靜態成員,它影響了 instance of 的判定

            語法:
            obj instance of A
            等效於
            A[Symbol.hasInstance](obj)  // function.prototype[Symbol.hasInstance]

            可以參與js的內部實現:

            Symbol.isConcatSpreadable = true 可以影響 contact 數組的扁平化

            Symbol.toPrimitive = function(type){}  可以影響類型轉換

            Symbol.toStringTag = ""   影響返回Object.prototype.tostring 的值
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章