Symbol类型

一、Symbol类型

symbol 是一种基本数据类型 (primitive data type)。每个从Symbol()返回的symbol值都是唯一的。

不支持语法:"new Symbol()":从 ECMAScript 6 开始不再被支持原始数据类型创建一个显式包装器对象。 然而,现有的原始包装器对象,如 new Booleannew String以及new Number,因为遗留原因仍可被创建。所以目前只有Symbol类型不能创建包装器对象。

直接使用Symbol()创建新的symbol类型,并用一个可选的字符串作为其描述。主要是为了在控制台显示,或者转为字符串时,比较容易区分

var sym1 = Symbol();
var sym2 = Symbol('foo');
var sym3 = Symbol('foo');

上面的代码创建了三个新的symbol类型。 注意,Symbol("foo") 不会强制将字符串 “foo” 转换成symbol类型。它每次都会创建一个新的 symbol类型。

注意,Symbol函数的参数只是表示对当前 Symbol 值的描述,因此相同参数的Symbol函数的返回值是不相等的。

Symbol("foo") === Symbol("foo"); // false

 Symbol 值可以显式转为字符串。

let sym = Symbol('My symbol');

String(sym) // 'Symbol(My symbol)'
sym.toString() // 'Symbol(My symbol)'

Symbol 值也可以转为布尔值,但是不能转为数值。

let sym = Symbol();
Boolean(sym) // true
!sym  // false

if (sym) {
  // ...
}

Number(sym) // TypeError
sym + 2 // TypeError

 作为对象的属性,写法上要用[ ]变量的形式

        let sym = Symbol();
        let obj = {
            [sym]: function (arg) {
                console.log(arg);  //123
            }
        };
        obj[sym](123);

 只有上述方式可以操作和获取Symbol键,以下方式不可以:

因为Symbol的唯一性,对象属性的Symbol("foo")和打印的Symbol("foo")属性不是一个

        var obj = {
            [Symbol("foo")] : 1
        }
        console.log(obj[Symbol("foo")]); 

获取对象的symbol类型的属性名:

Symbol 作为属性名,遍历对象的时候,该属性不会出现在for...infor...of循环中,也不会被Object.keys()Object.getOwnPropertyNames()JSON.stringify()返回。

但是,它也不是私有属性,有一个Object.getOwnPropertySymbols()方法,可以获取指定对象的所有 Symbol 属性名。该方法返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。注意,每个初始化的对象都是没有自己的symbol属性的,因此这个数组可能为空,除非你已经在对象上设置了symbol属性。

        const obj = {};
        let a = Symbol('a');
        let b = Symbol('b');

        obj[a] = 'Hello';
        obj[b] = 'World';

        const objectSymbols = Object.getOwnPropertySymbols(obj);// [Symbol(a), Symbol(b)]

 

        var sym = Symbol("foo");
        var obj = {
            [sym] : 1
        }
        console.log(Object.getOwnPropertyDescriptors(obj));

二、Symbol方法

Symbol.for()方法和  Symbol.keyFor()

有时,我们希望重新使用同一个 Symbol 值,Symbol.for()方法可以做到这一点。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建一个以该字符串为名称的 Symbol 值,并将其注册到全局

        let sym1 = Symbol.for('foo');
        let sym2 = Symbol.for('foo');

        sym1 === sym2 // true

Symbol.for()不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值。比如,如果你调用Symbol.for("cat")30 次,每次都会返回同一个 Symbol 值,但是调用Symbol("cat")30 次,会返回 30 个不同的 Symbol 值。

注意:Symbol.for()的值, symbol 注册表中的值

        let sym1 = Symbol.for('foo');
        let sym2 = Symbol.for('bar');
        console.log(sym1,sym2);      Symbol(foo) Symbol(bar)

Symbol.keyFor(sym) 方法用来获取 symbol 注册表中某个 symbol 关联的键

        let sym1 = Symbol.for('foo');
        let sym2 = Symbol.for('bar');
        console.log(Symbol.keyFor(sym1),Symbol.keyFor(sym2)); foo bar

三、Symbol属性

1、Symbol.iterator 为对象定义了默认的迭代器。该迭代器可以被 for...of 循环使用。

当需要对一个对象进行迭代时(比如开始用于一个for..of循环中),它的@@iterator方法都会在不传参情况下被调用,返回的迭代器用于获取要迭代的值。

一些内置类型拥有默认的迭代器行为,其他类型(如 Object)则没有。下表中的内置类型拥有默认的@@iterator方法:

(1)数组

Symbol在对象中存在的形式:

let sym = Symbol("foo");
var obj = {
    [sym]: function(){}
}
console.log(obj);

 

数组中[Symbol.iterator]属性

        let arr = [1,2,3];
        console.log(arr.valueOf());//数组没有该方法,继承对象的该方法
        console.log(arr.values()); //ES6新增方法
        console.log(arr[Symbol.iterator]()); //该方法也指向values函数体

结果:iterator对象 ——> Array Iterator对象 ——> Object

(2)字符串

字符串中[Symbol.iterator]属性

let str = new String("abc");
console.log(str[Symbol.iterator]()); //得到iterator对象

 结果:该iterator对象 ——>  String Iterator对象 ——>  Object

 

(3)Map

(4)Set

属性

  1. Symbol.iterator
  2. Symbol.unscopables

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值