25.JavaScript的Symbol类型、隐藏属性、全局注册表
文章目录
- Symbol类型的使用
- Symbol简介
- Symbol类型的描述
- Symbol不会隐式转字符串
- Symbol类似作为对象的属性键
- 创建Symbol键
- for…in中被跳过
- 隐藏自定义属性
- Symbol全局注册表
- 系统Symbol
- 总结
Symbol类型的使用
在前文《JavaScript的8种数据类型》中,我们已经简单的介绍过了JavaScript
的Symbol
类型,下面对其使用方法和使用场景做一个简单的介绍。
Symbol简介
Symbol
类型是JavaScript
中的一种特殊的类型,特殊在所有的Symbol
类型值都互不相同。我们可以使用“Symbol”来表示唯一的值,下面是创建Symbol
对象的案例:
let id = Symbol();
这样我们就创建了一个Symbol
类型的值,并把这个值存储在了变量id
中。
Symbol类型的描述
我们在创建一个Symbol
类型变量的时候,可以在参数中传入一些秒属性的字符串,用于描述这个变量的用途信息。
例如:
let id1 = Symbol('狂拽酷炫吊炸天的小明的id');
let id2 = Symbol('低调奢华有内涵的婷婷的id');
Symbol
类型在任何时候都是不同的,即使他们拥有相同的描述信息,描述只是一个标签,除此之外就没有别的用途了,例如:
let id1 = Symbol('id');
let id2 = Symbol('id');
console.log(id1==id2);//false
这个标签存在的意义,个人认为和Symbol
不能直观的看到内部具体值的特性有关,通过添加一个描述信息,让我们对变量的用途有更直观的了解。
Symbol不会隐式转字符串
JavaScript
中的大多数类型都可以直接转换成字符串类型输出,所以我们不能直观的看到它的值到底是什么,例如我们可以直接用alert(123)
把数字123
转换成字符串弹出。
但是Symbol
类型比较特殊,它不能直接转换,例如:
let id = Symbol();
alert(id);//报错,不能把Symbol类型转为字符串
JavaScript
中的Symbol
类型不能转成字符串是由于其内在的防治语言混乱的“语言保护”机制,因为字符串和Symbol
在本质上有着区别,不应该将其中一个转换成另一个。
试想一下,如果Symbol
可以转为字符串,那么它就变成了一个生成独一无二字符串的函数,就不再具备独立数据类型的必要。
如果我们真的想知道Symbol
变量的值,我们可以使用.toString()
方法,如下所示:
let id = Symbol('this is identification');
console.log(id.toString());//Symbol(this is identification);
或者使用.description
属性,获取描述信息:
let id = Symbol('加油,奥利给');
console.log(id.description);//加油,奥利给”
Symbol类似作为对象的属性键
根据JavaScript
的规范,只有两种类型的值可以作为对象的属性键:
- 字符串
- Symbol
如果使用其他类型,则会隐式的转为字符串类型。对象的键在前面的章节有详细的介绍,这里不再重复。
创建Symbol键
将Symbol
作为键值有两种方法:
例1:
let id = Symbol('id');
let user = {};
user[id] = 'id value';//添加Symbol键
console.log(user[id]);//id value
例2:
let id = Symbol('id');
let user = {[id]:'id value',//注意这里的方括号
};
console.log(user[id]);
以上两个案例展示了在对象中插入Symbol
类型作为键的用法,需要注意的是,在访问属性时需要使用obj[id]
而不是obj.id
,因为obj.id
代表的是obj[‘id’]
。
如果我们使用Symbol
作为对象的键会有什么效果呢?
for…in中被跳过
Symbol
非常明显的一个特征是,如果对象中使用Symbol
作为键,那么使用for…in
语句是访问不到Symbol
类型的属性的。
举个例子:
let id = Symbol('id');
let user = {name : 'xiaoming',[id] : 'id',
};
for (let key in user) console.log(user[key]);
执行以上代码,得到以下结果:
> xiaoming
可以发现,[id]
对象的值没有被打印出来,说明在对象属性列表中,使用for … in
会自动忽略Symbol
类型的键。
同样的,Object.keys(user)
也会忽略所有的Symbol
类型的键。
这样的特性能带来非常有用的效果,例如我们可以创建只能自己能用的属性。
虽然我们没有办法直接获取到Symbol
键,但是Object.assign
方法能够复制所有的属性:
let id = Symbol();
let obj = {[id] : '123'
}let obj2 = Object.assign({},obj);
console.log(obj2[id]);
这并不影响Symbol
的隐藏属性,因为复制后的对象仍然无法获取Symbol
键。
隐藏自定义属性
由于Symbol
既不能直接转为字符串,我们没有办法直观的获得它的值,又不能通过for … in
获得对象的Symbol
属性,也就是说,如果没有Symbol
变量本身,我们就没有办法获得对象内部的对应属性。
因此,通过Symbol
类型的键值,我们可以隐藏属性,这些属性只能我们自己访问,其他人都看不到我们的属性。
举个例子:
我们在开发的过程中,需要和同事“张三”合作,而这个张三创建了一个非常好用的工具Tool
,Tool
是一个对象类型,我们想白嫖张三的Tool
,并在此基础上添加一些自己的属性。
我们就可以通过添加Symbol
类型的键:
let tool = {//张三写好了的Toolusage : "Can do anything",
}let name = Symbol("My tool obj");
tool[name] = "This is my tool";
console.log(tool[name]);
以上示例展示了如何在别人写好的对象上添加自己的属性,那么为什么要使用Symbol
类型而不是常规的字符串呢?
原因如下:
- 对象
tool
是别人写好的代码,原则上我们不应该去修改别人的代码,这样会造成风险; - 避免命名冲突,我们直接使用字符串很有可能会和别人原有的属性键冲突,造成严重的后果;
- 使用
Symbol
永远不会发生命名冲突,因为Symbol
都是不同的; - 别人无法访问
Symbol
类型的键,相当于不会和别人的代码冲突;
错误示范:
如果我们不使用Symbol
类型,很可能出现以下情况:
let tool = {//张三写好了的Toolusage : "Can do anything",
}tool.usage = "Boom Boom";
console.log(tool.usage);
以上代码由于重复使用”usage”,从而重写了原属性,会造成对象原功能异常。
Symbol全局注册表
所有的Symbol
变量都是不同的,即使他们有用相同的标签(描述)。
有些时候,我们希望通过一个字符串名称(标签),访问同一个Symbol
对象,例如我们在代码的不同地方访问相同的Symbol
。
JavaScript
会维护一个全局的Symbol
注册表,我们可以通过向注册表中插入Symbol
对象,并为对象起一个字符串名称访问该对象。
向注册表插入或者读取Symbol
对象需要使用Symbol.for(key)
方法,如果注册表中有名为key
的对象,就返回该对象,否则就插入新对象再返回。
举个例子:
let id1 = Symbol.for('id');//注册表内没有名为id的Symbol,创建并返回
let id2 = Symbol.for('id');//注册表内已有名为id的Symbol,直接返回
console.log(id1===id2);//true
我们通过Symbol.for(key)
就能以全局变量的方式使用Symbol
对象,并使用一个字符串标记对象的名字。
相反的,我们还可以使用Symbol.keyFor(Symbol)
反向的从对象获取名称。
举个例子:
let id = Symbol.for('id');//注册表内没有名为id的Symbol,创建并返回
let name = Symbol.keyFor(id);
console.log(name);//id
Symbol.keyFor()
函数只能用在全局Symbol
对象上(使用Symbol.for
插入的对象),如果用在非全局对象上,就会返回undefined
。
举个例子:
let id = Symbol('id');//局部Symbol
let name = Symbol.keyFor(id);
console.log(name);//undefined
系统Symbol
JavaScript
有许多系统Symbol
,例如:
Symbol.hasInstance
Symbol.iterator
Symbol.toPrimitive
它们各有用途,我们在后面的会逐步介绍道这些独特的变量。
总结
Symbol
对象的值是唯一的;Symbol
可以添加一个标签,并通过标签在全局注册表中查询对象的实体;Symbol
作为对象的键无法被for … in
探测到;- 我们可以通过
Symbol
到全局注册表访问全局的Symbol
对象;
但是,Symbol
并不是完全隐藏的,我们可以通过Object.getOwnPropertySymbols(obj)
获取对象所有的Symbol
,或者通过Reflect.ownKeys(obj)
获取对象所有的键。
25.JavaScript的Symbol类型、隐藏属性、全局注册表相关推荐
- ES6 Symbol类型的应用、symbol属性名的遍历、Symbol.for()Symbol.keyFor()
目录 Symbol类型 介绍 Symbol.prototype.description Symbol的应用 1 给对象内追加属性 2 消除魔术字符串 symbol属性名的遍历 Symbol.for() ...
- 通过注册表更改Windows网络类型(公共网络、专用网络或家庭网络);
通过注册表更改Windows网络类型: 通过注册表更改网络类型的键值是: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion ...
- 通过修改注册表实现Windows 隐藏账户
Windows 隐藏账户 以下在windows 2003上操作<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:o ...
- mscoreei.dll没有被指定在windows上运行_windows注册表详解
与INI文件不同的是: 1.注册表采用了 二进制形式登录数据: 2.注册表支持子键,各级子关键字都有自己的"键值": 3.注册表中的键值项可以包含可执行代码,而不是简单的字串: 4 ...
- 命令编写注册表文件修改注册表项
命令编写注册表文件修改注册表项 1.何谓REG文件 REG文件实际上是一种注册表脚本文件,双击REG文件即可将其中的数据导入到注册表中.利用REG文件我们可以直接对注册表进行任何修改操作,它对注册表的 ...
- 注册表“.REG”文件完全攻略
我们平时对注册表的修改操作大多是通过注册表编辑器Regedit来实现的,然而有一天,你登录了某个网站以后,便发现注册表编辑器已经被禁止使用了,怎么办?最简单也是最方便而且不需要任何工具的办法,那就是使 ...
- 注册表的使用-入门篇
电脑出了问题,卸载软件注册表留下的东西太多清理不完--整理了一下以前了解的注册表的使用方法.因为现在第三方软件太多了,但个人觉得改善系统的第三方软件还不够完善,本人能力有限,还希望大家多提宝贵意见: ...
- 编写注册表文件修改注册表项
编写注册表文件修改注册表项 1.何谓REG文件 REG文件实际上是一种注册表脚本文件,双击REG文件即可将其中的数据导入到注册表中.利用REG文件我们可以直接对注册表进行任何修改操作,它对注册表的操作 ...
- 保护系统:WinXP中赤手空拳备份注册表(转)
保护系统:WinXP中赤手空拳备份注册表(转)[@more@] 本文以Windows XP为例(其他Windows版本可参考操作),介绍使用Windows"记事本"程序查找.修改注 ...
最新文章
- php图片保存在mysql_php实现上传图片保存到数据库的方法
- 正则表达式-我在学习过程中研究过的
- Web 应用服务器端渲染入门指南
- 教你如何写框架------用中文构建脚本
- 三星公布三款新型车用芯片 向大众供应
- 95-10-070-启动-SocketServer启动
- 无人机综合管理系统/web端后台管理系统/设备管理/运维管理/维护管理/人员管理/维修保养/配件管理/保养管理/团队管理/axure后台管理原型/axure原型/web端后台管理原型/rp原型
- Chrome格式化json
- [翻译] KGModal
- vs code 的便捷使用
- GoF的23种设计模式分类概念
- java翁凯_翁凯-JAVA
- 达芬奇剪辑调色专用键盘DaVinci Resolve Speed Editor
- 算法提高 7-2求arccos值
- MySQL的金科玉律:“不要使用SELECT *”
- C/C++遍历文件夹指定文件
- 7-1 婚宴座次排定
- 解决WPS在Linux下字体缺失
- PaddleOCR windows10下的安装使用
- vpb输出范围地形命令
热门文章
- aws上传找不到endpoint url或者The Aws Access Key Id you provided does not exist in our recordss
- 极验3forbidden,易盾d包
- KUKA机器人 - 从开机到自动运行
- 计算机私密相册安全吗,一张照片竟能泄露这么多隐私?这个功能不可不知
- 上云节省 35%计算资源,420 个运维人天:运满满实时计算实践和思考
- foxmail怎么群发邮件
- 《支付系统-3交易系统》
- BZOJ1016 || 洛谷P4208 [JSOI2008]最小生成树计数【矩阵树定理】
- 【今日CV 计算机视觉论文速览 第94期】 4 Apr 2019
- html页面长按保存图片,h5长按保存图片