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 
       }
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容

  • 本人是android开发的,由于最近React Native的火热,再加上自己完全不懂JS的语法,俗话说的好"落后...
    Bui_vlee阅读 282评论 0 0
  • SwiftDay011.MySwiftimport UIKitprintln("Hello Swift!")var...
    smile丽语阅读 3,830评论 0 6
  • 概述 ES5的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加...
    oWSQo阅读 515评论 1 3
  • 1.概述 ES5的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象...
    赵然228阅读 802评论 2 10
  • 本届学生基本素养很好,加上管理到位,目前状态相当不错。进入复习后,在与学生的互动中也隐约发现了一些问题,就想在工作...
    最美初阳阅读 151评论 1 3