Symbol

今年最火的莫过于 ES6 + Babel 了。ES6 引入了一些很实用很强大的特性和一些语法。今天说的 Symbol 就是其中一个。

对于这个新特性,很多人估计很少使用它,尤其是可见性封装特别好的时候。但它也有很应用场景的。
那Symbol 到底是个什么东西呢?

数据类型

首先它是 ES6 引入的一个 JS 数据类型。熟悉 JavaScript 的都知道,JavaScript 有七大数据类型。

null, undefined, number, boolean, string, Array、object
// 基本数据类型:null、undefined、数字、布尔、字符串
// 复杂数据类型: 数组、对象等

而Symbol 就是类似这些的一种数据类型。利用 typeof 运算符它的结果如下:

typeof Symbol() === 'symbol'// 为 true

现在已经定位它是什么了,那它有什么用呢?
Symbol() 用于解决属性名的冲突。比如,对于同一个对象 obj,A 对其加了属性 a, 之后B修改代码也想对其加属性 a,此时如果不知情的情况下就会产生覆盖问题。
举个应用场景,比如一个人名叫“张三”,他可能拥有两个国家甚至更多国家的国籍,因此会有多个身份 Id号。此时我们直观的做法就是加 Id 属性:

var person = {name: "zhangsan",id: "XXXXX", // 可能多个age: 20
}

也会有人说,用数组就好,那每个国家的 id 怎么获取?

var person = {name: "zhangsan",id: ["XXXXX", 'YYYYY'] // 哪个是中国人身份证的 id ?age: 20
}

此时若是用 Symbol 便能很好的解决问题。因为传入对象属性时,同样的Symbol不相等。看下面:

Symbol('key') === Symbol('key')  // false, 因为Symbol('key') 

Symbol('key') 两次的返回值是不同的,且是独一无二的值。

现在解决上面的问题。

var person = {name: "zhangsan",age: 20
}// Symbol('key') 生成引用类型,独一无二的,所以 chinaId 与 americaId 不等。
var chinaId = Symbol('id');
var americaId = Symbol('id');person[chinaId] = "chinaId";
person[americaId] = "americaId";

如下:

语法

生成一个 Symbol 很容易, 直接调用 Sysmbol() 即可,当然也可以传个参数作为描述。

var sym = Symbol();// 参数: 只是个描述
// 只是为了在控制台显示,或者转为字符串时,比较容易区分
var sym2 = Symbol('I am just a description');
sym2.toString()
// "Symbol(I am just a description)"

另外,还可以用 Symbol.for 生成一个 Symbol

var keySym = Symbol.for('key');

只是这里有点不同于上面:

Symbol.for('key') === Symbol.for('key');// 这里为  true

这说明,两次使用 Symbol.for('key') 生成的结果一样。
Symbol.for()与Symbol()这两种写法,都会生成新的Symbol。它们的区别是,前者会在全局环境中供搜索,后者不会。Symbol.for()不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值。因此这里的参数与生成的 Symbol 有关。两种方式用于不同的场景。

var keySym = Symbol.for('key');
Symbol.keyFor(keySym) // "key"

特性

独一无二

这个特性上面已经说了,每次 调用 Symbol('key') 都会产生一个独一无二的值。比如调用 Symbol('key')  10次,就会得到 10 个 Symbol 类型的对象。

存取

读取和修改都很方便,只是不能用 obj.prop 的形式访问。注意,这里是修改 对象的 Symbol 类型的属性。

console.log(person[chinaId]); // ok
person[chinaId] = "zhangsanId";// ok
console.log(person.chinaId); // 输出 undefined

虽然不能用 obj.prop 形式访问,但还是可以用下面三种方式的。

var obj = {};
var symProp = Symbol();// 第一种
var obj = {[symProp]: 'YYYY'
};// 第二种
obj[symProp] = 'XXXX';// 第三种写法
Object.defineProperty(obj, symProp, { value: 'ZZZZ' });

只读

对应 Symbol 类型的对象,它是只读的。对它添加属性不起作用。
Symbol("key").name = 1;
// 文档里说会 TypeError
// 不过我在 Chrome 控制台使用时发现,只是不起作用而已。

下面是个例子:

var sb = Symbol('key');
sb.name = "zw";
console.log(sb);
console.log(sb.name);


上面代码中,我们对 Symbol('key') 的 name 属性赋值, 然后访问,只得到 undefined .

遍历

我们给对象添加了 Symbol() 属性,不过它终归不是普通属性。像 for...in 、 Object.keys(obj) 、Object.getOwnPropertyNames(obj)会忽略Symbol,即属性自身不可枚举。

var person = {name: "zhangsan",age: 20
}
var chinaId = Symbol('id');
person[chinaId] = "chinaId";for( var prop in person) {console.log(person[prop]);
}
Object.keys(person);
Object.getOwnPropertyNames(person);


从上图看,三种遍历确实只访问了 两个基本属性,而Symbol 属性被忽略。

那怎么遍历呢?两个方法:

Object.getOwnPropertySymbols(person) //获取Symbol属性名,但是也会忽略内置的Symbol
Reflect.ownKeys(obj) //获取所有的属性名

另外,它还有一些实用的属性和方法,有兴趣的可以自己尝试下。官网

ES6新数据类型Symbol相关推荐

  1. JavaScript基础: ES6新特性---Symbol

    简介 在ES6中引入的一种新的基本数据类型Symbol.这个类型不像是number或者String让人使用起来那样顺手好理解,为什么是这样呢?是不是因为其是新特性,所以不熟是正常的? 自然不是因为箭头 ...

  2. es6 新增数据类型Symbol

    es6在string number boolean null undefined object之外又新增了一种Symbol类型. Symbol意思是符号,有一个特性-每次创建一个Symbol值都是不一 ...

  3. ES6新特性总结(2)解构赋值、模板字符串、Symbol

    ES6新特性总结(2)解构赋值.模板字符串.Symbol 1 解构赋值 1.1 Spread / Rest 操作符 1.2 数组的解构 1.3 对象的解构 1.4 解构的默认值和参数的解构 2 模板字 ...

  4. ES6新增数据类型:Symbol

    [学习es6新增的数据类型 Symbol] 1.symble 的作用 symbol 是 es6 新增的一个基本的数据类型,定义唯一值的:一般用于给对象添加私有属性. 2.symble 的用法 < ...

  5. web前端技巧-ES6新特性与重点知识汇总(二)

    ES6框架的新特性我们今天再来介绍其他的一些,还是带好写本本做好笔记,我们马上开始. 七.扩展运算符 扩展运算符(spread)是三个点(-).它好比 rest 参数的逆运算,将一个数组转为用逗号分隔 ...

  6. ES6新增数据类型符号(1):普通符号

    在编程时,我们会遇到某些属性,我们不需要或者不想要别人访问它,即需要设置私有属性,如下例,我们不需要在外部获取getRandom这一属性 const game = {attack: 30, //攻击力 ...

  7. ES6入门之Symbol

    ES5对象属性名都是字符串容易造成属性名的冲突. eg:var a = { name: 'lucy'};a.name = 'lili';这样就会重写属性 ES6引入了一种新的原始数据类型Symbol, ...

  8. 【ES6(2015)】Symbol

    文章目录 1. 声明方式 2. Symbol.for() 3. Symbol.keyFor() 4. 作为属性名 5. 属性遍历 6. 消除魔术字符串 ES6 引入了一种新的原始数据类型 Symbol ...

  9. Javascript - ES6新语法概览

    Javascript - ES6新语法概览 简介 ES6是JavaScript语言的新一代标准,加入了一些新的功能和语法,正式发布于2015年6月,亦称ES2015:该标准由ECMA(欧洲计算机制造联 ...

最新文章

  1. 刚看完 Kafka 源码,各位随便问!
  2. hadoop中的序列化与Writable类
  3. 让我们努力从“不可救药的乐观主义者”--华尔街知名投资人约翰。多尔那里学点东西(永远放弃尝试改变这个世界)...
  4. 图形处理(二)固定边界参数化
  5. 深入浅出python机器学习_9.1_数据预处理_sklearn.preprocessing.StandardScaler MinMaxScaler RobustScaler Normalizer
  6. java 并发 线程安全_Java并发教程–线程安全设计
  7. 想不到,三级缓存是这样解决循环依赖的……
  8. train problem I (栈水题)
  9. 【PL/SQL】匿名块、存储过程、函数、触发器
  10. Python项目开发公用方法--excel生成方法
  11. 街头篮球Android和苹果,街头篮球手游ios和安卓数据可以互通吗?
  12. 准备一个月,考过软件系统架构师
  13. 笔记本电脑外接显示器完全攻略(图文说明)
  14. 阿里云服务器访问windows下网页(内网穿透)
  15. 《ssh权威指南》书评
  16. 计算机电源MOD,电源全模组和非模组究竟有什么区别?
  17. 用生物知识解读“新冠病毒”,生物竞赛、高考考点,先马后看!
  18. 集合竞价 连续竞价 开盘价如何产生
  19. mc服务器 领地插件配置文件,《我的世界》领地插件 领地插件详细使用教程
  20. 大学计算机专业游戏本推荐,选这几款就对了!大学生笔记本电脑盘点推荐

热门文章

  1. java打印心_使用java打印心型与圆形图案实现代码示例
  2. 学习记录575@网络分层下各层密码算法概述
  3. 计算机投影仪的作用是什么,投影仪电脑接口类型及其用途详细介绍【图】
  4. 精选Android中高级面试题 -- 终局之篇:高级干货
  5. Symfony学习笔记之管理CSS和JavaScript-----现代前端实践 Webpack Encore总结
  6. MEMS 惯性传感器 - 参数指标误差介绍
  7. ngnix location 配置规则详解
  8. 配置简单的Git服务器
  9. Photoshop-图层样式的使用方法
  10. 测试面试基础问答(加解析)