ES6新特徵之Symbol

基本概念

Symbol:表示獨一無二的值,屬於類字符串數據類型,本質上能夠當字符串來用。數組

基本用法

  • Symbol是JavaScript的第七種數據類型,前六種分別是undefined、null、Boolean、String、NUmber、Objects、Symbol。
    // 1
        let symbol = Symbol();
        typeof symbol
        // symbol 
    
        // 2 Symbol使用時不能使用new,它是一個函數,能夠接收參數,僅做爲描述 
        let symbol1 = Symbol('week');
        symbol1;
        // Symbol(week) 
    
        symbol1.toString();
        // "Symbol(week)"
    
        // 3
        let symbol1 = Symbol();
        let symbol2 = Symbol();
        symbol1 === symbol2;
        // false 
    
        let symbol1 = Symbol('object');
        let symbol2 = Symbol('object');
        symbol1 === symbol2;
        // false 
    
        // 4 隱式轉換
        const obj = {
            toString() {
                return 'object';
            }
        };
        const symbol = Symbol(obj);
        symbol;
        // Symbol(object) 
    
        // 5 不能參與運算 
        let symbol = Symbol('symbol');
        "hello" + symbol;
        // TypeError: Cannot convert a Symbol value to a string 
    
        // 6 類型轉換 
        String(symbol);
        symbol.toString();
        // Symbol(symbol) 
    
        let symbol = Symbol();
        Boolean(symbol);
        // true
    
        Number(symbol);
        // TypeError: Cannot convert a Symbol value to a number
  • description ,Symbol的描述
    const symbol = Symbol('symbollobmys');
        symbol.description;
        // "symbol"
  • symbol應用場景,對象屬性名
    let symbol = Symbol();
        let a = {};
        a[symbol] = 'Hello!';
    
        let a = {
            [symbol]: 'Hello!'
        };
    
        let a = {};
        Object.defineProperty(
            a,
            symbol,
            {
                value: 'Hello!'
            }
        );
  • 屬性遍歷 屬性遍歷中的for...in、for...of、Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()都不會返回Symbol,它們會把Symbol過濾掉。可是咱們能夠有兩種方法獲得Symbol,一種是Object.getOwnPropertySymbols,另外一種是Reflect.ownKeys。
    const obj = {};
        let symbol1 = Symbol('symbol1');
        let symbol2 = Symbol('symbol2');
        obj[symbol1] = 'symbol1';
        obj[symbol2] = 'symbol1';
        Object.getOwnPropertySymbols(obj);
        // [Symbol(symbol1), Symbol(symbol2)] 
    
    
        Reflect.ownKeys(obj);
        // [Symbol(symbol1), Symbol(symbol2)] 
    
        // 能夠做爲非私有的內部方法
  • Symbol.for(是惟一一個能讓兩個Symbol相等的),尋找全局的環境下某個描述下面的這個Symbol,若是找到某一個描述下的Symbol,那麼就會返回這個Symbol,若是沒有找到就會生成一個新的Symbol。簡而言之就是,返回當前索引Symbol。
    let symbol1 = Symbol.for('week');
        let symbol2 = Symbol.for('week');
        symbol1 === symbol2;
        // true
  • Symbol.keyFor,返回已登記的Symbol的key
    let symbol1 = Symbol.for("symbol1");
        Symbol.keyFor(symbol1);
        // symbol1 
    
        let symbol2 = Symbol("week");
        Symbol.keyFor(symbol2);
        // undefined

內置的Symbol

  • Symbol.hasInstance,instanceof運算符調用
    class MyClass {
            [Symbol.hasInstance](obj) {
                return obj instanceof Array;
            }
        }
    
        [1, 2, 3] instanceof new MyClass();
        // true
  • Symbol.isConcatSpreadable,控制數組concat是否展開
    let array1 = [1, 2];
        [3, 4].concat(array1, 5);
        // ['a', 'b', 'c', 'd', 'e'] 
        array1[Symbol.isConcatSpreadable];
        // undefined 
    
        let array2 = [1, 2];
        array2[Symbol.isConcatSpreadable] = false;
        [3, 4].concat(array2, 5);
        // [3, 4, [1, 2], 5]
  • Symbol.species,爲衍生類指定原型
    class MyArray extends Array {
        }
    
        const one = new MyArray(1, 2, 3);
        const two = a.map(x => x);
        const three = a.filter(x => x = 1);
    
        b instanceof MyArray;
        // true 
        c instanceof MyArray;
        // true 
    
        class MyArray extends Array {
            static get [Symbol.species]() { return Array; }
        }
    
        const one = new MyArray(1, 2, 3);
        const two = a.map(x => x);
        const three = a.filter(x => x = 1);
    
        b instanceof MyArray;
        // false 
        c instanceof Array;
        // true
  • Symbol.match ,str.match調用
    class Mather {
            [Symbol.match](string) {
                return 'hello world';
            }
        }
        'e'.match(new Mather());
        // 'hello world'
  • Symbol.replace,replace調用
    const demo = {};
        demo[Symbol.replace] = () => 'hello word';
        'Hello'.replace(demo, 'World');
        // hello word
  • Symbol.search
  • Symbol.split
  • Symbol.iterator,默認遍歷器
    const diyIterable = {};
        diyIterable[Symbol.iterator] = function* () {
            yield 'hello';
            yield 'word';
        };
        [...diyIterable];
        // ['hello', 'word']
  • Symbol.toPrimitive ,類型轉換調用
    let object = {
            [Symbol.toPrimitive](hint) {
                switch (hint) {
                case 'number':
                    return 1;
                case 'string':
                    return 'hello';
                case 'default':
                    return 'word';
                default:
                    throw new Error('Cannot convert');
                }
            }
        };
    
        2 * object;
        // 2 
        3 + object;
        // '3word' 
        object == 'word';
        // true 
        String(object);
        // hello
  • Symbol.toStringTag , 指定[object Object]或[object Array]中object後面字符串
    ({
            [Symbol.toStringTag]: 'Hello'
        }.toString())
        // "[object Hello]"
  • Symbol.unscopables , 指定被with排除的屬性,with是一個語句,它能夠擴展一個做用域鏈
    // with語句 擴展一個語句的做用域鏈 
        var a, x, y;
        var r = 10;
        with (Math) {
            a = PI * r * r;
            x = r * cos(PI);
            y = r * sin(PI / 2);
        }
    
        class MyClass {
            week() {
                return 1;
            }
            get [Symbol.unscopables]() {
                return { week: true };
            }
        }
    
        var week = function () { return 2; };
        with (MyClass.prototype) {
            week();
            // 2 
        }
相關文章
相關標籤/搜索