您的位置:首页 > Web前端 > JavaScript

在ES6中引入了JavaScript的第7中基本数据类型你知道吗

2018-11-13 22:52 232 查看

概述

ES5的对象名都是字符串,这很容易造成命名冲突。

ES6引入了一种原始的数据类型Symbol,表示独一无二的值。它是JavaScript语言的第7中数据类型。

Symbol值通过Symbol函数生成。也就是说属性名可以有两种类型:一种是原有的字符串,另一种就是新增的Symbol类型。

[code]let s = Symbol();

typeof s   //”symbol”

注:Symbol函数前不能使用new命令,否则会报错。这是因为生成的Symbol是一个原始类型的值,不是对象。

Symbol函数可以接受一个字符串作为参数,表示对Symbol实例的描述。

[code]var s1 = Symbol(‘foo’);

var s2 = Symbol(‘bar’);

s1  //  Symbol(foo)

S2  //  Symbol(bar)

s1.toString()   //”Symbol(foo)”

s2.toString()   //”Symbol(bar)”

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

[code]var s1 = Symbol();

var s2 = Symbol();

s1 === s2   //false

var s1 = Symbol(‘foo’);

var s2 = Symbol(‘foo’);

s1 === s2   //false

Symbol还具有以下几点特性:

Symbol值不能与其他类型的值进行运算,否则会报错。

Symbol值可以显示转化为字符串。

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

作为属性名的Symbol

由于每一个Symbol值都不相等,这意味着Symbol值可以作为标识符用于对象的属性名,保证不会出现同名的属性。

[code]var mysymbol = Symbol();

//第一种写法

var a = {};

a[mysymbol ] = ‘hello’;

//第二种写法

var a = {

[mysymbol ] = ‘hello’;

};

//第三种写法

var a = {};

Object.defineProperty(a, mysymbol , { value: ‘hello’});

注:Symbol值作为对象名时不能使用点运算符。

Symbol类型还可以用于一组常量,保证这组常量的值都不相等。

[code]log.levels = {

DEBUG:Symbol(‘debug’),

INFO:Symbol(‘info’)

}

常量使用Symbol值的最大好处就是,其他任何值都不可能有相同的值。

注:Symbol值作为属性名时,该属性还是公开属性,不是私有属性。

属性名的遍历

Symbol作为属性名,该属性不会出现在for ... in、for ... of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()返回。但是它也不是一个私有属性,有一个Object.getOwnPropertySymbols方法可以获取指定对象的所有Symbol属性名。

Object.getOwnPropertySymbols方法返回一个数组,成员是该对象的所有用作属性名的Symbol值。

[code]var obj = {

‘c’ : ‘c’

};

var a = Symbol(‘a’);

var b = Symbol(‘b’);

obj[a] = ‘hello’;

obj[b] = ‘word;

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

另外一个新的API--Reflect.ownKeys方法也可以返回所有的类型的键名,包括常规的键名和Symbol键名。

[code]Reflect.ownKeys(obj);  // [ ‘c’ , Symbol(a), Symbol(b)]

Symbol.for()、Symbol.keyFor()

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

[code]var s1 = Symbol.for(‘foo’);

var s2 = Symbol.for(‘foo’);

s1 === s2    //true

Symbol,for()与Symbol()这两种方法都会生成新的Symbol。他们的区别是,前者会被登记在全局环境中搜索,后者不会。

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

[code]Symbol.for(“bar”) === Symbol.for(“bar”)    //true

Symbol(“bar”) === Symbol(“bar”)    //false

注:Symbol.for为Symbol值登记的名字是全局环境的,可以在不同的iframe或service worker中取到同一值。

内置的Symbol值

除了定义自己使用的Symbol值,ES6还提供了11个内置的Symbol值,指向语言内部使用的方法

在这里我把他们都罗列出来,就不一一的具体详细解释说明了,有兴趣的朋友可以去查阅一下详细使用说明。

Symbol.hasInstanse

指向一个内部方法,对象使用instanceof运算符时会调用这个方法,判断该对象是否为某个构造函数的实例。

Symbol.isConcatSpreadable

等于一个布尔值,表示该对象使用Array.prototype.concat()时是否可以展开。

Symbol.species

指向当前对象的构造函数。

Symbol.match

指向一个函数,当执行str.match(myObject)时,如果该属性存在,会调用它返回该方法的返回值。

Symbol.replace

指向一个方法,当对象被String.prototype.replace方法调用时会返回该方法的返回值。

Symbol.search

指向一个方法,当对象被String.prototype.search方法调用时会返回该方法的返回值。

Symbol.split

指向一个方法,当对象被String.prototype.split方法调用时会返回该方法的返回值。

Symbol.iterator

指向该对象的默认遍历器方法。

Symbol.toPrimitive

指向一个方法,对象被转为原始类型的值时会调用这个方法,返回该对象对应的原始类型值。

Symbol.toStringTag

指向一个方法,在对象上调用Object.prototype.toString方法时,如果这个属性存在,其返回值会出现在toString方法返回的字符串中,表示对象的类型。

Symbol.unscopables

指向一个对象,指定了使用with关键字时哪些属性会被with环境排除。

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: