zoukankan      html  css  js  c++  java
  • ES6学习笔记(9)----Symbol

    参考书《ECMAScript 6入门》
    http://es6.ruanyifeng.com/

    Symbol
    1.symbol:Symbol是javascript的第七种原始数据类型,代表独一无二的值。前六种是Null,undefined,Boolean,String,Number,Object
      生成symbol值的方式
        let s1 = Symbol()
        let s2 = Symbol('s2-symbol')//接受字符串作为参数来对symbol值进行描述
        typeof s1 // Symbol
        typeof s2 //Symbol
      Symbol值是独一无二的
        let s3 = Symbol()
        let s4 = Symbol("s2-symbol")
        s1 == s3 //false
        s1 === s3 //false
        Object.is(s1,s3) //false
        s2 == s4 //false
        s2 === s4 //false
        Object.is(s2,s4) //false
        let obj = {name:"testSymbol"}
        Symbol(obj) //Symbol([object Object])
        let c = Symbol(obj)
        c //Symbol([object Object])
        c === Symbol(obj) //false
        s2//Symbol(s2-symbol)
        String(s2)//'Symbol(s2-symbol)'
        s2.toString()//'Symbol(s2-symbol)'
        'abc'+s2 //报错 Uncaught TypeError: Cannot convert a Symbol value to a string
        'abc'+s2.toString //"abcfunction toString() { [native code] }"
    2.作为属性名的symbol
      let symbolA = Symbol('A');
      let symbolB = Symbol('B');
      a.在对象外部,可以使用方括号和defineProperty方法两种方式将对象的属性名指定为symbol类型
        let obj2 = {}
        obj2[symbolA] = "test";
        Object.defineProperty(obj2,symbolB,{value:"abc"});
        obj2//{Symbol(A): "test", Symbol(B): "abc"}
      b.读取对象中属性名为symbol的属性时,要用方括号,不能用点运算.
        obj2.symbolA //undefined
        obj2.symbolB //undefined
        obj2[symbolA] //"test"
        obj2[symbolB] //"abc"
      c.在对象内部使用symbol定义对象的属性时,symbol必须放在对象当中
        let obj3 = {
          [symbolA] : "obj3-Symbol",
          [symbolB](){
            return "test symbolB"
          }
        }
        obj3//{Symbol(A): "obj3-Symbol", Symbol(B): ƒ}
      d.symbol可以用来定义常量,由于其独一无二的特性,可以使代码精确度更高
        const staticVariable = Symbol();
    3.属性名的遍历
      Symbol定义的属性不是私有属性,但是并不能被常规方法遍历到,目前只能通过Reflect.ownKeys(obj)和Object.getOwnPropertySymbols(obj)两种方式遍历对象中的symbol属性
      Reflect.ownKeys(obj4)//[Symbol(A), Symbol(B)]
      Object.getOwnPropertySymbols(obj4)//[Symbol(A), Symbol(B)]
    4.Symbol.for(),Symbol.keyFor()
      Symbol()与Symbol.for()
      相同点:都会生成新的Symbol
      不同点
      Symbol()每次都会生成新的Symbol,即使修饰参数一致。
      Symbol.for(key)每次调用时,先会检查给定的key是否存在,如果存在,则返回这个已有的key对应的symbol值,如果不存在,则生成新的symbol值
      let test1 = Symbol('test1');
      let test2 = Symbol.for('test1');
      let test3 = Symbol.for('test3');
      let test4 = Symbol.for('test3');
      test1 === test2 //false Symbol('test1')不会登记在全局环境中供搜索,所以Symbol.for('test1')在全局环境中搜索不到test1对应的symbol值,因此重新生成了一个symbol值。
      test3//Symbol(test3)
      test3 === test4 //true
      Symbol.keyFor():返回一个已经登记的symbol值的key
      Symbol.keyFor(test2)//'test1'
    5.内置的Symbol值
      Symbol.hasInstance
      Symbol.isConcatSpreadable:用于判断一个数组或类数组调用concat时是否需要展开
        数组:Symbol.isConcatSpreadable 默认值是undefined,代表展开;值为true时也代表展开,值为false时也代表不展开
        let arr1 = [1,2,3];
        let arr2 = [4,5,6];
        let arr3 = ['a','b','c'];
        arr1[Symbol.isConcatSpreadable]//undefined 展开
        arr2[Symbol.isConcatSpreadable] = true;展开
        arr3[Symbol.isConcatSpreadable] = false;不展开
        arr3.concat(arr1,arr2)//[['a','b','c'], 1, 2, 3, 4, 5, 6]
        类数组:Symbol.isConcatSpreadable值为true时代表不展开,值为false或者undefined时代表展开
        let obj1 = {length:2,0:'a',1:'b'};
        let obj2 = {length:3,0:'aa',1:'bb',2:'cc'};
        let obj3 = {length:2,'0':'aaa',1:'bbb'};
        obj1[Symbol.isConcatSpreadable];//undefined 不展开
        obj2[Symbol.isConcatSpreadable] = true;展开
        obj3[Symbol.isConcatSpreadable] = false;不展开
        [].concat(obj3,obj1,obj2);//[{0: "aaa", 1: "bbb", length: 2, Symbol(Symbol.isConcatSpreadable): false}, "aa", "bb", "cc", {0: "a", 1: "b", length: 2}]
      Symbol.species:对象的Symbol.species属性,指向一个构造函数。创建衍生对象时,会使用该属性。
      定义Symbol.species属性要采用get取值器,默认的Symbol.species等同于下面的写法。
      static get[Symbol.species](){return this;}
      Symbol.match:对象的Symbol.match属性,对应一个方法。当对象的String.prototype.match方法调用时,会返回该方法的返回值。
      Symbol.replace:对象的Symbol.replace属性,对应一个方法。当对象的String.prototype.replace方法调用时,会返回该方法的返回值。
      Symbol.search:对象的Symbol.search属性,对应一个方法。当对象的String.prototype.search方法调用时,会返回该方法的返回值。
      Symbol.split:对象的Symbol.split属性,指向一个方法。当该对象被String.prototype.split方法调用时,会返回该方法的返回值。
      Symbol.iterator:对象的Symbol.iterator属性,指向对象的默认遍历器方法
      Symbol.toPrimitive:对象的Symbol.toPrimitive属性指向一个方法。该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。
        let obj = {};
        2*obj //NaN
        2+obj //"2[object boolean]"
        '[object boolean]' == obj //true
        等同于
        let obj = {
          [Symbol.toPrimitive](hint) {
           switch (hint) {
            case 'number':
              return NaN;
            case 'string':
              return 'str';
            case 'default':
              return '[object boolean]';
            default:
              throw new Error();
          }
         }
        };
        
      Symbol.toStringTag:对象的Symbol.toStringTag属性指向一个方法,在该对象上调用Object.prototype.toString方法时,如果它的属性存在,它的返回值会出现在toString方法返回的字符串之中,表示对象的类型。这个属性可以用来定制表示对象类型的如[object string]中   object后面的字符串
      let obj = {"name" : "test"};
      obj[Symbol.toStringTag] = 'boolean';
      Object.prototype.toString.call(obj) //"[object boolean]"
      Symbol.unscopables:对象的Symbol.unscopables属性指定一个对象,该对象规定当使用with关键字时,哪些属性会被with环境排除

  • 相关阅读:
    用nginx转发请求tomcat 如何配置访问日志获取真实ip
    jquery扩展方法(extend) 写法
    android binder机制
    rails nginx passenger postgre 在ubuntu部署
    ssh 免密码登陆
    佛山 开发者 程序员 ios 安卓 外包团队
    佛山程序猿交流群
    IOS开发 僵尸调试
    关于产品设计的功能
    android 视图(view)置顶
  • 原文地址:https://www.cnblogs.com/carolddz/p/8675223.html
Copyright © 2011-2022 走看看