系列文章 -- ES6笔记系列

Symbol是什么?中文意思是标志、记号,顾名思义,它可以用了做记号。

是的,它是一种标记的方法,被ES6引入作为一种新的数据类型,表示独一无二的值。

由此,JS的数据类型多了一位成员:

Number、String、Boolean、undefined、Object、Symbol

一、简单使用

1. 声明

类似字符串String的声明方式 var str = 'str'; Symbol的声明方式类似,它调用构造函数Symbol()

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

2. 使用

Symbol声明了是为了使用

var s = Symbol();
var s1 = Symbol(); console.log(s, s1);
console.log(s == s1); // false

Chrome的输出中自动对Symbol类型的数据做了标识处理,由输出知道,虽然通过Symbol生成的两个标志不相同,但两个变量混淆了分不清。

实际上,为了区别出不同的symbol,我们可以在参数中指定

var s = Symbol('s');
var s1 = Symbol('s1'); console.log(s, s1);

symbol除了简单的在控制台输出之外,还可以参与到其他代码逻辑运算中去,最常见的是在对象属性名称中(为确保属性名惟一而存在)

var s = Symbol();
var s1 = Symbol('s1'); var obj = {
[s]: function() {
console.log(1);
},
[Symbol()]: () => {
console.log(2);
},
[s1]: 3
}; obj[s]() //
obj[s1] //

注意到symbol要使用[]中括号包裹起来,调用的时候也一样(不能使用obj.s的方式,这样会被识别成字符串)

3. 属性的遍历

如上代码,如果我们想遍历对象的属性值,也许会这样操作

for (var item in obj) {
if (typeof obj[item] === 'function') {
obj[item]();
} else {
console.log(obj[item]);
}
} Object.keys(obj).forEach(function(item) {
if (typeof obj[item] === 'function') {
obj[item]();
} else {
console.log(obj[item]);
}
});

却发现什么也没输出

因为要获取到Symbol这个属性名,ES6引入了新的方法,旧的for...in  Object.keys()、Object.getOwnPropertyNames()等不支持访问

使用新的getOwnPropertySymbols方法

var s = Symbol();
var s1 = Symbol('s1'); var obj = {
[s]: function() {
console.log(1);
},
[Symbol()]: () => {
console.log(2);
},
[s1]: 3,
a: 4
}; Object.getOwnPropertySymbols(obj).forEach(function(item) {
if (typeof obj[item] === 'function') {
obj[item]();
} else {
console.log(obj[item]);
}
}); // 输出 1 2 3

虽然识别了symbol类属性,但常规属性却被忽略了,所以ES6还引入了一个新的内置类Reflect,它的ownKeys方法可以识别出所有属性名

var s = Symbol();
var s1 = Symbol('s1'); var obj = {
[s]: function() {
console.log(1);
},
[Symbol()]: () => {
console.log(2);
},
[s1]: 3,
a: 4
}; Reflect.ownKeys(obj).forEach(function(item) {
if (typeof obj[item] === 'function') {
obj[item]();
} else {
console.log(obj[item]);
}
}); // 输出 4 1 2 3

4. 类型转换

数字转换成字符串我们可以简单的使用 + '' 实现,symbol呢

var s = Symbol();
var s1 = Symbol('s1'); s + '' // Uncaught TypeError: Cannot convert a Symbol value to a string

出错了,提示不能转换。

实际上,我们只是不能直接转换值,还是可以用toString或String方法转换这个标志的

var s = Symbol();
var s1 = Symbol('s1'); s.toString() // Symbol()
String(s1) // Symbol(s1)

类似的,也可以转换为bool值

var s = Symbol();
var s1 = Symbol('s1'); !!s // true
!s // false
Boolean(s1) // true

不过,symbol是不能转换成数值Number类型的

5. Symbol.for()相同值的使用

有时候我们需要使用同一个symbol值,而调用Symbol()的时候会自动创建不同的值

var temp = [];

var scores = [{
name: 'jack',
score: 10
}, {
name: 'pick',
score: 20
}, {
name: 'pick',
score: 30
}]; scores.forEach(function(item) { temp.push({
name: Symbol(item.name),
score: item.score
});
}); temp[1].name == temp[2].name // false

以上代码主要为了登记不同用户的分数,并确保唯一性使用了symbol,但最终用户名都为pick的项不想等,可能会导致后续的计算出错

把Symbol换成Symbol.for,输出才为true

两者类似,都可以生成一个Symbol类型的值,但后者是先判断全局中是否有该symbol值,有就返回该值,没有才创建,并将该值登记在全局中

var s = Symbol.for('s');
var s1 = Symbol.for('s'); s == s1 // true
s === s1 // true var s = Symbol('s');
var s1 = Symbol('s'); s == s1 // false
s === s1 // false

此外,我们可以用Symbol.keyFor()访问全局中的symbol相关项,没有则返回undefined

var s = Symbol.for('s');
var s1 = Symbol.for('s'); Symbol.keyFor(s) // s
Symbol.keyFor(s1) // s
Symbol.keyFor(s2) // Uncaught ReferenceError: s2 is not defined var s3 = Symbol('s3');
Symbol.keyFor(s3) // undefined

6. Symbol的更多使用

Symbol的更多使用方法,可参考MDN - Symbol

ES6笔记(4)-- Symbol类型的更多相关文章

  1. ES6中的Symbol类型

    前面的话 ES5中包含5种原始类型:字符串.数字.布尔值.null和undefined.ES6引入了第6种原始类型——Symbol ES5的对象属性名都是字符串,很容易造成属性名冲突.比如,使用了一个 ...

  2. ES6学习----let、const、解构赋值、新增字符串、模板字符串、Symbol类型、Proxy、Set

    这篇es6的学习笔记来自于表哥 表严肃,是我遇到过的讲课最通透,英文发音最好听的老师,想一起听课就去这里吧 https://biaoyansu.com/i/hzhj1206 ES6就是JS6,JS的第 ...

  3. 用vue.js学习es6(四):Symbol类型

    一.Symbol类型: 1.ES6引入了一种新的原始数据类型Symbol,表示独一无二的值.它是JavaScript语言的第七种数据类型,前六种是:Undefined.Null. 布尔值(Boolea ...

  4. ES6中关于数据类型的拓展:Symbol类型

    ES5中包含5种原始类型:字符串.数值.布尔值.null.undefined.ES6引入了第6种原始类型——Symbol. ES5的对象属性名都是字符串,很容易造成属性名冲突.比如,使用了一个他人提供 ...

  5. ES6学习笔记(9)----Symbol

    参考书<ECMAScript 6入门>http://es6.ruanyifeng.com/ Symbol1.symbol:Symbol是javascript的第七种原始数据类型,代表独一无 ...

  6. ES6笔记系列

    ES6,即ECMAScript 6.0,ES6的第一个版本是在2015年发布的,所以又称作ECMAScript 2015 如今距ES6发布已经一年多的时间,这时候才去学,作为一个JSer,羞愧羞愧,还 ...

  7. ES6笔记(6)-- Set、Map结构和Iterator迭代器

    系列文章 -- ES6笔记系列 搞ES6的人也是够无聊,把JS弄得越来越像Java.C++,连Iterator迭代器.Set集合.Map结构都出来了,不知道说什么好... 一.简单使用 1. iter ...

  8. ES6笔记一

    遍历数组: 1:传统的 for (var index = 0; index < myArray.length; index++) { console.log(myArray[index]);} ...

  9. ES6笔记(3)-- 解构赋值

    系列文章 -- ES6笔记系列 解构赋值,即对某种结构进行解析,然后将解析出来的值赋值给相关的变量,常见的有数组.对象.字符串的解构赋值等 一.数组的解构赋值 function ids() { ret ...

随机推荐

  1. 如何基于RabbitMQ实现优先级队列

    概述 由于种种原因,RabbitMQ到目前为止,官方还没有实现优先级队列,只实现了Consumer的优先级处理. 但是,迫于种种原因,应用层面上又需要优先级队列,因此需求来了:如何为RabbitMQ加 ...

  2. javascript的执行和预解析

    很久以前遇到过一个面试题目,的的确确是面试官问我的问题,下面是这个问题的代码部分.由于年少无知,没有回答上,被无情pass了. var u ='hello world'; ;(function(){ ...

  3. 软件测试基本理论-IBM模式

    软件测试基本理论(1) IBM生产模式 1   参考书目 <IBM-从菜鸟到测试架构师-一个测试工程师的成长日记> 出版社:电子工业出版社 印次:2013年6月 作者:IBM主要工程师 2 ...

  4. js中各种跨域问题实战小结(一)

    什么是跨域?为什么要实现跨域呢? 这是因为JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.也就是说只能访问同一个域中的资源.我觉得这就有必要了解下javascript中的同源策略 ...

  5. 项目开发之使用 maven

    本文将详述 maven 在软件项目中的使用.首先讲述 maven 的基本工作原理及环境的搭建.然后讲述开发及配置管理人员如何使用 maven,最后将介绍 maven 与 eclipse 集成使用. m ...

  6. 从Windows中卸载Apache

    在重装Apache或者妳不再需要它的时候,这时就需要将它卸载. 下面是步骤: 打开开始菜单(win8中ÿ+X)或者我的电脑(废话) 找到并打开Apache的安装目录(Program Files\Apa ...

  7. sublime 3 快捷键

    来自(http://dengo.org/archives/970) Sublime text 3是我最喜欢的代码编辑器,每天和代码打交道,必先利其器,掌握基本的代码编辑器的快捷键,能让你打码更有效率. ...

  8. 《OOC》笔记(1)——C语言const、static和extern的用法

    <OOC>笔记(1)——C语言const.static和extern的用法 C语言中const关键字用法不少,我只喜欢两种用法.一是用于修饰函数形参,二是用于修饰全局变量和局部变量. 用c ...

  9. 分享最新的博客到LinkedIn Timeline

    使用Octopress作为我的博客框架有两年了.使用起来一直很顺手,这个工具真正的把博客跟写代码等同起来,非常酷炫.再加上各种各样的定制化,简直是随心所欲.我针对自己的需求对Octopress框架进行 ...

  10. Git学习笔记(2)——版本的回退,和暂存区的理解

    本文主要记录了版本的回退,以及工作区,暂存区概念的理解. //开始之前,先回顾上次的内容,修改文件如下,并提交到版本库. Git is a distributed version control sy ...