Symbol学习笔记

栏目: JavaScript · 发布时间: 5年前

内容简介:ES5的对象属性名都是字符串,这容易造成属性名的冲突。ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,前六种是:undefined、null、布尔值、字符串、数值、对象。Symbol值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来的字符串,另一种就是新增的Symbol类型。凡是属性名属于Symbol类型,就都是独一无二的,可以保证不会与其它属性名产生冲突。上面代码中,变量s就是一个独一无二的值。typeof运算符的

1.概述

ES5的对象属性名都是字符串,这容易造成属性名的冲突。ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,前六种是:undefined、null、布尔值、字符串、数值、对象。

Symbol值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来的字符串,另一种就是新增的Symbol类型。凡是属性名属于Symbol类型,就都是独一无二的,可以保证不会与其它属性名产生冲突。

let s = Symbol();
typeof s//symbol

上面代码中,变量s就是一个独一无二的值。typeof运算符的结果,表明变量s是Symbol数据类型,而不是字符串之类的其它类型。

Symbol函数可以接受一个字符串作为参数,表示对Symbol实例的描述,主要是为了控制台显示,或者转为字符串时,比较容易区分。

let s1 = Symbol('foo');
let s2 = Symbol('bar');
s1//Symbol(foo);
s2//Symbol(bar);
s1.toString()//'Symbol(foo)'
s2.toString()//'Symbol(bar)'

如果Symbol的参数是一个对象,就会调用该对象的toString方法,将其转为字符串,然后才生成一个Symbol值。

const obj = {
  toString() {
    return 'abc';
  }
};
const sym = Symbol(obj);
sym // Symbol(abc)

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

// 没有参数的情况
let s1 = Symbol();
let s2 = Symbol();

s1 === s2 // false

// 有参数的情况
let s1 = Symbol('foo');
let s2 = Symbol('foo');

s1 === s2 // false

上面代码中,s1和s2都是symbol函数的返回值,而且参数相同,但是它们是不相等的。

2.作为属性名的Symbol

由于每一个Symbol值都是不相同的,这意味着Symbol值可以作为标识符,用于对象的属性名,就能保证不会出现同名的属性。这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。

let mySymbol = Symbol();
//第一种写法
let a = {};
a[mySymbol] = 'Hello!';
//第二种写法
let a = {
    [mySymbol]:'Hello!'
};
//第三种写法
let a = {};
Object.defineProperty(a,mySymbol,{value:'Hello!'})
//以上写法都得到同样的结果
a[mySymbol]//'Hello!'

上面代码通过方括号结构和Object.defineProperty,将对象的属性名指定为一个Symbol值。注意:Symbol值作为对象属性名时,不能用点运算符。

const mySymbol = Symbol();
const a = {};
a.mySymbol = 'Hello!';
a[mySymbol]//undefined;
a['mySymbol']//'Hello!'

上面代码中,因为点运算符后面总是字符串,所以不会读取mySymbol作为标识名所指代的那个值,导致a的属性名实际上是一个字符串,而不是一个Symbol值。

同理,在对象的内部,使用Symbol值定义属性时,Symbol值必须放在方括号之中。

let s = Symbol();
let obj = {
    [s]:function(arg){...}
}

上面代码中,如果s不放在方括号中,该属性的键名就是字符串s,而不是s所代表的那个Symbol值。采用增强的对象写法,上面代码的obj对象可以写的更简洁一些。

let obj = {
    [s](arg){...}
}

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

const log = {};
log.levels = {
  DEBUG: Symbol('debug'),
  INFO: Symbol('info'),
  WARN: Symbol('warn')
}
console.log(log.levels.DEBUG, 'debug message');
console.log(log.levels.INFO, 'info message');

下面是另一个例子。

const COLOR_RED    = Symbol();
const COLOR_GREEN  = Symbol();

function getComplement(color) {
  switch (color) {
    case COLOR_RED:
      return COLOR_GREEN;
    case COLOR_GREEN:
      return COLOR_RED;
    default:
      throw new Error('Undefined color');
    }
}

常量使用 Symbol 值最大的好处,就是其他任何值都不可能有相同的值了,因此可以保证上面的switch语句会按设计的方式工作。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Cascading Style Sheets 2.0 Programmer's Reference

Cascading Style Sheets 2.0 Programmer's Reference

Eric A. Meyer / McGraw-Hill Osborne Media / 2001-03-20 / USD 19.99

The most authoritative quick reference available for CSS programmers. This handy resource gives you programming essentials at your fingertips, including all the new tags and features in CSS 2.0. You'l......一起来看看 《Cascading Style Sheets 2.0 Programmer's Reference》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换