Javascript ES6中数据类型Symbol的使用详解


Posted in Javascript onMay 02, 2017

介绍

Symbol 是一种特殊的、不可变的数据类型,可以作为对象属性的标识符使用,表示独一无二的值。Symbol 对象是一个 symbol primitive data type 的隐式对象包装器。

它是JavaScript语言的第七种数据类型,前6种分别是:Undefined、Null、Boolean、String、Number、Object。

语法

Symbol([description])

Parameters

description : 可选的字符串。可用于调试但不访问符号本身的符号的说明。如果不加参数,在控制台打印的都是Symbol,不利于区分。

demo

var s1 = Symbol('symbol1');
s1 //Symbol(symbol1);

因为Symbol函数返回的值都是独一无二的,所以Symbol函数返回的值都是不相等的。

//无参数
var s1 = Symbol();
var s2 = Symbol();

s1 === s2 // false

//有参数
 var s1 = Symbol('symbol');
 var s2 = Symbol('symbol');

 s1 === s2 //false

作为属性名的Symbol

由于每一个Symbol值都是不相等的,那么作为属性标识符是一种非常好的选择。

定义方式:

let symbolProp = Symbol();

var obj = {};
obj[symbolProp] = 'hello Symbol';

//或者
var obj = {
 [symbolProp] : 'hello Symbol';
}

//或者
var obj = {};
Object.defineProperty(obj,symbolProp,{value : 'hello Symbol'});

注意:

定义属性的时候只能将Symbol值放在方括号里面,否则属性的键名会当做字符串而不是Symbol值。同理,在访问Symbol属性的时候也不能通过点运算符去访问,点运算符后面总是字符串,不会读取Symbol值作为标识符所指代的值.

Symbol类型定义常量

常量的使用Symbol值最大的好处就是其他任何值都不可能有相同的值,用来设计switch语句是一种很好的方式。例如:消除魔术字符串(这里留给读者思考,如果有什么疑问,可以给我留言)

Symbol.for(),Symbol.keyFor()

Symbol.for()

对于Symbol.for方法需要记住两点:

  • Symbol.for()所返回的Symbol值的作用域是整个代码库(包括不同的iframe或者service worker),是一个全局的变量,第一次产生的时候就会登记下来。
  • 调用Symbol.for()的时候,如果在全局环境中检索给定的key是否存在,如果不存在才会新建一个值,而Symbol()不会,Symbol()每次返回的都是不同的值。
Symbol.for('foo') === Symbol.for('foo'); //true
Symbol('foo') === Symbol('foo'); //false

Symbol.keyFor()

Symbol.keyFor方法返回一个已登记的Symbol类型的值的key。

var s1 = Symbol.for('foo');
Symbol.keyFor(s1) //"foo"
var s2 = Symbol('foo');
Symbol.keyFor(s2);//undefiend

上面的代码中,变量s2属于未登记的Symbol值,所以返回undefined

属性名的遍历

Symbol作为属性名,虽然不是私有属性,但是在for…in,for…of循环中,Object.keys() ,Object.getOwnPropertyNames()都不会获取到。通常通过两种方法达到Symbol属性的遍历。

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

Reflect.ownKeys()可以返回所有类型的键名,包括包括常规的键名和Symbol键名.

下面给出一个例子来解释上面所有的。

var obj = {};
var a = Symbol('a');
var b = Symbol('b');
obj[a] = 'hello';
obj[b] = 'world';
//获取不到
for(var i in obj){
 console.log(i); //无输出
}
Object.getOwnPropertyNames(obj);//[]
//可以获取
var objectSymbols = Object.getOwnPropertySymbols(obj);
objectSymbols// [Symbol(a), Symbol(b)]
Reflect.ownKeys(obj);//[Symbol(a), Symbol(b)]

以Symbol值作为名称的属性不会被常规方法遍历所得到。我们可以利用这个特性,为对象定义一些非私有但又希望只用于内部的方法。

var size = Symbol('size');
class Collection {
 constructor(){
 this[size] = 0;
 }
 add(item){
 this[this[size]] = item;
 this[size]++;
 }
 static sizeOf(instance){
 return instance[size];
 }
}
var x = new Collection();
Collection.sizeOf(x); //0
x.add('foo');
Collection.sizeOf(x); //1
Object.keys(x)//['0']
Object.getOwnPropertyNames(x) //['0']
Object.getOwnPropertySymbols(x) //[Symbol(size)]

上面的代码中,对象x的size属性是一个Symbol值,所以Object.keys(x) Object.getOwnPropertyNames(x)都无法获取它。这就造成了一种非私有的内部方法的效果。如果对ES6定义类方面还不清楚的,可以先不看这段,或者自己查查资料,后面的文章我也会分享出来,总的来说现在JavaScript的新标准越来越像Java了,比如新增的const、let块级作用域,class定义类等等。

内置的Symbol值

除了自己定义的Symbol值外,JavaScript有一些内置的Symbol表示的内部语言行为不在ECMAScript 5及以前暴露给开发者。这些Symbol可以被访问被下列属性:

1、Symbol.iterator

返回对象的默认迭代器的方法。被for…of使用

2、Symbol.math

与字符串匹配的方法,也用于判断对象是否可以用作正则表达式.被 String.prototype.match()使用。

3、Symbol.replace

一种方法取代匹配字符串的子串。被String.prototype.replace()使用。

4、Symbol.search

返回与正则表达式匹配的字符串内返回索引的方法。被String.prototype.search()使用。

5、Symbol.split

在与正则表达式匹配的索引处拆分字符串的方法。被String.prototype.split()使用.

6、Symbol.hasInstance

确定构造函数对象是否将对象作为实例识别的方法。被instanceof使用

7、Symbol.isConcatSpreadable

一个布尔值,指示对象是否应该被扁平化为数组元素。被Array.prototype.concat()使用.

8、Symbol.unscopables

从关联对象的环境绑定中排除其自身和继承的属性名称的对象值。被with使用

9、Symbol.species

用于创建派生对象的构造函数。

10、Symbol.toPrimitive

将对象转换为原始值的方法。

11、Symbol.toStringTag

用于对象的默认描述的字符串值。被Object.prototype.toString()使用.

我这里没给出具体的例子,针对这11个属性。读者自己主动去把这几个属性搞懂,对理解有些方法是非常有用的。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
jQuery使用手册之二 DOM操作
Mar 24 Javascript
Mozilla 表达式 __noSuchMethod__
Apr 05 Javascript
jquery+ajax每秒向后台发送请求数据然后返回页面的代码
Jan 17 Javascript
jQuery模拟超链接点击效果代码
Apr 21 Javascript
JavaScript 创建运动框架的实现代码
May 08 Javascript
jquery控制页面部分刷新的方法
Jun 24 Javascript
JS简单实现禁止访问某个页面的方法
Sep 13 Javascript
jQuery模拟淘宝购物车功能
Feb 27 Javascript
JS简单判断字符在另一个字符串中出现次数的2种常用方法
Apr 20 Javascript
Node.Js中实现端口重用原理详解
May 03 Javascript
ES6 Map结构的应用实例分析
Jun 26 Javascript
解决Vue中的生命周期beforeDestory不触发的问题
Jul 21 Javascript
Bootstrap实现基于carousel.js框架的轮播图效果
May 02 #Javascript
Vue2.x中的父子组件相互通信的实现方法
May 02 #Javascript
详解webpack 配合babel 将es6转成es5 超简单实例
May 02 #Javascript
jQuery树插件zTree使用方法详解
May 02 #jQuery
JavaScript数据结构学习之数组、栈与队列
May 02 #Javascript
js-FCC算法-No repeats please字符串的全排列(详解)
May 02 #Javascript
详解webpack+es6+angular1.x项目构建
May 02 #Javascript
You might like
修改apache配置文件去除thinkphp url中的index.php
2014/01/17 PHP
PHP小偷程序的设计与实现方法详解
2016/10/15 PHP
php把时间戳转换成多少时间之前函数的实例
2016/11/16 PHP
php安装php_rar扩展实现rar文件读取和解压的方法
2016/11/17 PHP
PHP基于DateTime类解决Unix时间戳与日期互转问题【针对1970年前及2038年后时间戳】
2018/06/13 PHP
php实现的表单验证类完整示例
2019/08/13 PHP
php获取微信openid方法总结
2019/10/10 PHP
javascript克隆对象深度介绍
2012/11/20 Javascript
有关于eclipse配置spket需要注意的一些地方
2013/04/07 Javascript
一个JavaScript去除字符串末尾的空白实例代码
2014/09/22 Javascript
浅析javascript的间隔调用和延时调用
2014/11/12 Javascript
jQuery实现转动随机数抽奖效果的方法
2015/05/21 Javascript
vue中,在本地缓存中读写数据的方法
2018/09/21 Javascript
Javascript如何实现扩充基本类型
2020/08/26 Javascript
[40:05]LGD vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
[05:15]2018年度CS GO社区贡献奖-完美盛典
2018/12/16 DOTA
用Python实现通过哈希算法检测图片重复的教程
2015/04/02 Python
深入讲解Python函数中参数的使用及默认参数的陷阱
2016/03/13 Python
Python使用回溯法子集树模板解决爬楼梯问题示例
2017/09/08 Python
pandas数值计算与排序方法
2018/04/12 Python
用TensorFlow实现多类支持向量机的示例代码
2018/04/28 Python
Python基于lxml模块解析html获取页面内所有叶子节点xpath路径功能示例
2018/05/16 Python
对python的文件内注释 help注释方法
2018/05/23 Python
OpenCV 轮廓检测的实现方法
2019/07/03 Python
Django 使用easy_thumbnails压缩上传的图片方法
2019/07/26 Python
Python字符串中添加、插入特定字符的方法
2019/09/10 Python
pycharm下配置pyqt5的教程(anaconda虚拟环境下+tensorflow)
2020/03/25 Python
CSS3实现可关闭的下拉手风琴菜单效果
2015/08/31 HTML / CSS
html5手机键盘弹出收起的处理
2020/01/20 HTML / CSS
英国买鞋网站:Charles Clinkard
2019/11/14 全球购物
给交警的表扬信
2014/01/12 职场文书
护理专业自荐信范文
2014/02/26 职场文书
养牛场项目建议书
2014/05/13 职场文书
考研复习计划
2015/01/19 职场文书
2019如何书写演讲稿?
2019/07/01 职场文书
Mysql中的触发器定义及语法介绍
2022/06/25 MySQL