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 
     }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值