JavaScript的Symbol类型、隐藏属性及全局注册表详解

本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了关于symbol类型、隐藏属性及全局注册表的相关问题,包括了symbol类型的描述、symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

JavaScript的Symbol类型、隐藏属性及全局注册表详解

【相关推荐:javascript视频教程、web前端】

Symbol简介

Symbol类型是JavaScript中的一种特殊的类型,特殊在所有的Symbol类型值都互不相同。我们可以使用“Symbol”来表示唯一的值,下面是创建Symbol对象的案例:

let id = Symbol();

登录后复制

这样我们就创建了一个Symbol类型的值,并把这个值存储在了变量id中。

立即学习“Java免费学习笔记(深入)”;

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 = {//张三写好了的Tool    usage : "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 = {//张三写好了的Tool    usage : "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');//局部Symbollet name = Symbol.keyFor(id);console.log(name);//undefined

登录后复制

系统Symbol

JavaScript有许多系统Symbol,例如:

Symbol.hasInstanceSymbol.iteratorSymbol.toPrimitive

它们各有用途,我们在后面的会逐步介绍道这些独特的变量。

总结

Symbol对象的值是唯一的;Symbol可以添加一个标签,并通过标签在全局注册表中查询对象的实体;Symbol作为对象的键无法被for … in探测到;我们可以通过Symbol到全局注册表访问全局的Symbol对象;

但是,Symbol并不是完全隐藏的,我们可以通过Object.getOwnPropertySymbols(obj)获取对象所有的Symbol,或者通过Reflect.ownKeys(obj)获取对象所有的键。

【相关推荐:javascript视频教程、web前端】

以上就是JavaScript的Symbol类型、隐藏属性及全局注册表详解的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2700921.html

(0)
上一篇 2025年3月7日 19:10:58
下一篇 2025年2月19日 12:52:58

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 解决JavaScript数据处理的5个常见问题

    本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了关于数据处理中常见的一些问题,包括了数据的增删改查、数据的排序、数据的去重、平级列表变成树形结构以及数组对象相同项合并处理,下面一起来看一下,希望对大家有帮助。 【相关推…

    2025年3月7日 编程技术
    200
  • JavaScript总结之18种常用数组方法

    本篇文章给大家带来了关于javascript的相关知识,其中主要总结介绍了一些常用的数组方法,整理分成了不会改变原数组的方法和会改变原数组的方法,下面一起来看一下,希望对大家有帮助。 【相关推荐:javascript视频教程、web前端】 …

    2025年3月7日 编程技术
    200
  • JavaScript隐藏机制之垃圾回收知识总结

    本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了垃圾回收的相关问题,垃圾回收是javascript的隐藏机制,下面一起来看一下,希望对大家有帮助。 【相关推荐:javascript视频教程、web前端】 一、前言 垃圾…

    2025年3月7日 编程技术
    200
  • JavaScript类数组和可迭代对象的实现原理详解

    本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了关于类数组和可迭代对象的实现原理,包括了把对象本身构造成迭代器、string的迭代器等等相关内容,下面一起来看一下吧,希望对大家有帮助。 【相关推荐:javascript…

    2025年3月7日 编程技术
    200
  • 一文搞定JavaScript的节点操作

    本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了关于节点操作的相关问题,包括了父级节点、子节点、兄弟节点、增加删除复制节点等等内容,下面一起来看一下,希望对大家有帮助。 【相关推荐:javascript视频教程、web…

    2025年3月7日 编程技术
    200
  • 11个可以提升效率的chrome调试技巧

    本篇文章给大家分享11个chrome高级调试技巧,学会效率直接提升666%,希望对小伙伴们有帮助! chrome浏览器作为前端童鞋的老婆,相信你一定不陌生。调页面、写BUG、画样式、看php片少了它整个世界都不香了。 不信?一起来看看我们的…

    2025年3月7日 编程技术
    200
  • 简单了解JavaScript数据结构与算法之栈

    本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了关于栈的相关问题,包括了面向过程方法源码编写栈以及用面向对象的方法来源码书写等等内容,下面一起来看一下,希望对大家有帮助。 【相关推荐:javascript视频教程、we…

    2025年3月7日
    200
  • JavaScript迭代器知识点总结

    本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了关于迭代器的相关问题,迭代就是指可以从一个数据集中按照一定的顺序,不断取出数据的过程,下面一起来看一下,希望对大家有帮助。 【相关推荐:javascript视频教程、we…

    2025年3月7日 编程技术
    200
  • 深入聊聊JavaScript

    本篇文章给大家带来了关于javascript的相关知识,其中主要包括了为什么需要javascript引擎、浏览器内核与js引擎的关系、环境变量与记录等等内容,下面一起来看一下,希望对大家有帮助。 【相关推荐:javascript视频教程、w…

    2025年3月7日
    200
  • 一篇搞定JavaScript DOM详细操作

    本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了关于dom详细操作的相关问题,包括了什么是dom、什么是dom tree、怎么获取dom等等内容,下面一起来看一下,希望对大家有帮助。 【相关推荐:javascript视…

    2025年3月7日 编程技术
    200

发表回复

登录后才能评论