就唯一对象标识符而言,Symbol 的用途是什么?

2023-11-22

关于“不重复”的注释:

有人告诉我这是重复的javascript ECMAScript 6 中的 Symbol 有什么用?。嗯,这对我来说似乎不太合适。他们给出的代码是这样的:

const door = {};
// library 1
const cake1 = Symbol('cake');
door[cake1] = () => console.log('chocolate');
// library 2
const cake2 = Symbol('cake');
door[cake2] = () => console.log('vanilla');
// your code
door[cake1]();
door[cake2]();

唯一使这项工作成功的是因为cake1 and cake2是不同的(唯一的)名称。但开发商已经明确给出了这些;没有提供任何东西Symbol这在这里有帮助。

例如,如果你改变cake1 and cake2 to cake然后运行,会报错:

未捕获的语法错误:标识符“蛋糕”已被声明

如果您已经必须手动提出唯一标识符,那么该怎么办Symbol帮助?

如果您在控制台中执行此操作:

Symbol('cake') === Symbol('cake');

它评估为false。所以它们是独一无二的。但为了实际使用它们,您现在必须想出 2 个键名(cake1 and cake2)是独一无二的。这必须由开发人员手动完成;里面什么都没有Symbol或一般的 JavaScript 会对此有所帮助。您基本上是使用创建一个唯一标识符Symbol但随后必须手动将其分配给...您作为开发人员必须想出的唯一标识符。

关于链接的帖子,他们引用了这个例子不使用Symbol:

const door = {};
// from library 1
door.cake = () => console.log('chocolate');
// from library 2
door.cake = () => console.log('vanilla');

// your code
door.cake();

他们试图声称这是一个问题并且只会记录“vanilla”。很明显那是因为door.cake不是唯一的(它被声明了两次)。 “修复”就像使用一样简单cake1 and cake2:

door.cake1 = () => console.log('chocolate');
door.cake2 = () => console.log('vanilla');

door.cake1(); // Outputs "chocolate"
door.cake2(); // Outputs "vanilla"

现在可以工作并记录“巧克力”和“香草”。在这种情况下Symbol根本没有使用过,而且确实与该工作没有任何影响。这只是开发人员分配了唯一标识符的情况,但他们是手动完成的,并且没有使用Symbol.


原问题:

我正在学习 JavaScript 课程,演讲者正在讨论Symbol.

他在视频的开头说道:

Symbol 的特点是每一个都是unique这使得他们在对象属性标识符等方面非常有价值.

然而他接着说:

  1. 它们是不可枚举的for...in loops.
  2. 它们不能用于JSON.stringify。 (它会产生一个空对象)。

对于第(2)点,他给出了这个例子:

console.log(JSON.stringify({key: 'prop'})); // object without Symbol
console.log(JSON.stringify({Symbol('sym1'): 'prop'})); // object using Symbol

这个日志{"key": "prop"} and {}分别到控制台。

这如何使Symbol就唯一对象键或标识符而言“有价值”?

根据我的经验,您想要对对象执行的两件非常常见的事情是枚举它,或者将其中的数据转换为 JSON 以通过 ajax 或某种此类方法发送。

我不明白这样做的目的是什么Symbol是的,但特别是为什么你想使用它们来制作对象标识符?鉴于它会导致以后发生你无法做的事情。

编辑 - 以下是原始问题的一部分 - 但与实际目的相比是一个小问题Symbol关于唯一标识符:

如果您需要发送类似的内容{Symbol('sym1'): 'prop'}通过 ajax 到后端在这种情况下你实际上需要做什么?


我在另一个问题中回复了您的评论,但由于这是开放的,我将尝试详细说明。

您将变量名称与符号混合在一起,而它们彼此无关。

变量名只是引用值的标识符。如果我创建一个变量,然后将其设置为其他值,则这两个变量都引用相同的值(或者在 JavaScript 中的非基元的情况下,引用相同的值)。

在这种情况下,我可以这样做:

const a = Symbol('a');
const b = a;

console.log(a === b); // true

这是因为只创建了 1 个 Symbol,并且对该 Symbol 的引用被分配给 a 和 b。这不是您使用符号的目的。

符号旨在提供独特的keys它们与变量名不同。键用于对象(或类似对象)。我认为另一个例子的简单性可能会引起混乱。

让我们想象一个更复杂的例子。假设我有一个程序,可以让您创建人员地址簿。我将把每个人存储在一个对象中。

const addressBook = {};

const addPerson = ({ name, ...data }) => {
  addressBook[name] = data;
};

const listOfPeople = [];

// new user is added in the UI
const newPerson = getPersonFromUserEntry();

listOfPeople.push(newPerson.name);
addPerson(newPerson);

在这种情况下,我会使用listOfPeople显示一个列表,当您单击它时,它将显示该用户的信息。

现在的问题是,由于我使用的是这个人的名字,所以这并不是真正唯一的。如果我添加了两个“Bob Smith”,第二个将覆盖第一个,并且单击“listOfPeople”中的 UI 会将您带到两个用户的同一个 UI。

现在,我们不这样做,而是在addPerson()并将其返回并存储在listOfPeople.

const addressBook = {};

const addPerson = ({ name, ...data }) => {
  const symbol = Symbol(name);

  addressBook[symbol] = data;

  return symbol;
};

const listOfPeople = [];

// new user is added in the UI
const newPerson = getPersonFromUserEntry();

listOfPeople.push(addPerson(newPerson));

现在,每个条目listOfPeople是完全独一无二的。如果您单击第一个“鲍勃·史密斯”并使用该符号查找他,您将找到正确的符号。第二个也是如此。即使密钥的基础相同,它们也是唯一的。

正如我在另一个答案中提到的,用例Symbol实际上相当狭窄。实际上,只有当您需要创建一个您知道是完全唯一的密钥时。

您可能使用它的另一种情况是,如果您有多个独立的库,将代码添加到公共位置。例如,全球window object.

如果我的图书馆将某些内容导出到window名为“getData”,并且某人有一个库也导出“getData”,如果同时加载(无论谁最后加载),我们中的一个将覆盖另一个。

但是,如果我想更安全,而不是这样做:

window.getData = () => {};

我可以创建一个符号(我跟踪其引用),然后调用我的getData()带有符号:

window[getDataSymbol]();

我什至可以将该符号导出给我的库的用户,以便他们可以使用它来调用它。

(请注意,以上所有名称都是相当糟糕的命名,但同样,这只是一个示例。)

另外,正如有人在评论中提到的,这些符号不适合在系统之间共享。如果我打电话Symbol('a')这对于我的系统来说是完全独特的。我无法与其他人分享。如果您需要在系统之间共享,则必须确保强制执行密钥唯一性。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

就唯一对象标识符而言,Symbol 的用途是什么? 的相关文章

  • JavaScript 中的 touchstart 不再返回 TouchList

    我遇到了一个非常奇怪的问题 我正在绑定touchstart事件到一个元素 并且想要检索事件的 X 和 Y 坐标 全部文档 http developer apple com library safari documentation apple
  • 如何使用角度在垫选择嵌套值中包含过滤器

    我正在使用带有嵌套下拉菜单的有角材料 下拉值以父级和子级为基础嵌套 我面临两个问题 自动建议不起作用 如果我输入父名称或其关联的子名称 则必须以展开模式过滤并显示特定的父视图 如果我展开第一个父视图并尝试展开第二个父视图 则第一个父视图应在
  • 在 AngularJS 和 Nodejs 之间共享代码

    使用在前端和后端之间共享代码的最佳方式是什么javascript 特别是说之间nodejs and angularjs 问题是我们使用的是相同的enums and constant values例如error codes在后端和前端 现在
  • 使用 JavaScript 查找数组中最接近的日期

    我有一个包含天数的数组 每一天都是一个对象 例如 day year 2012 day month 08 day number 03 day name mon 我还通过使用以下方法向每个日期对象添加了时间戳属性 function conver
  • 如果用户禁用了 javascript,如何回退到完全不同的索引页面?

    我有一个大型 动态生成的单页网站 该网站严重依赖 javascript 我想为没有 javascript 的人提供后备 每个版本必须有不同的 php 代码 所以基本上我需要一个完全不同的索引页面 我不想将所有内容都包装在 javascrip
  • 如何对页面的某个部分进行实时更新?

    我需要刷新页面的各个部分 以便在有新数据时进行更新 我该怎么办 使用jquery 例子 是的 jQuery 非常适合这个 查看这些方法 http api jquery com category ajax http api jquery co
  • 如何使用 JavaScript 获取光标下的单词?

    如果我有 p some long text p 在我的 HTML 页面上 我如何知道鼠标光标位于 文本 一词上方 我的另一个答案仅适用于 Firefox 这个答案适用于 Chrome 也许在 Firefox 中也能工作 我不知道 funct
  • 是的验证;同一字段可以接受不同类型吗?

    我对是的很陌生 我试图验证字段可以是遵循某个正则表达式的字符串 也可以是此类字符串的数组 这是检查字符串与我的正则表达式匹配的工作示例 field yup string matches regex 现在我想要field如果它有一个这样的字符
  • 为什么 Bootstrap 按钮下拉菜单在 iOS 上不起作用?

    看起来甚至连引导演示在这里 http twitter github com bootstrap components html buttonDropdowns不适用于 iOS 您似乎无法在 iPhone 或 iPad 上从中选择项目 有解决
  • 在 NodeJs 中使用 Jest 模拟 Http Post 请求

    我有一个使用本机 https request 使用 Azure Function 内的 Node Js 构建的外部 POST API 一切正常 现在我正在尝试构建单元测试用例 并对模拟 Request 方法感到震惊 回调响应具有 on 功能
  • 切换 Ag-Grid 中的浮动过滤器?

    我试图通过开关或按钮单击来确定浮动过滤器的显示 看起来很简单 我应该能够在 true 和 false 之间切换 将该值提供给网格选项中的浮动过滤器 然后刷新标题 对吗 不幸的是 网格似乎总是落后一步 当我第一次点击时 什么也没有发生 当我将
  • JSON 解析错误 - JSON 中位置 1 处出现意外标记 o

    我需要获取一个 JSON 对象并记录标题控制台以实现自动完成功能 我的 json 的示例如下 title Example 1 url http www example1 com title Example 2 url http www ex
  • pointdown 与 onclick:有什么区别?

    两者有什么区别onpointerdown and onclick事件处理程序 有任何实际差异吗 事件在 DOM 树上传播的方式不一样吗 是否有一些设备仅响应这些事件之一 我最初以为这只是pointerdown在触摸设备或笔中触发 但是onc
  • 如何在 Electron 中使窗口大小响应。 (打开应用程序时)

    我最近开始在 Electron 上制作一个应用程序 我想让窗口具有响应能力 例如 如果我在不同的屏幕上打开应用程序 它应该根据屏幕尺寸以全尺寸打开 我的代码 app on ready gt const htmlPath path join
  • td 内的文本可以随 td 一起调整大小吗? (是其高度的百分比?)

    我有一个 100 占屏幕的表格 里面有 3x3 9 个单元格 每个单元格占 33 到目前为止 一切都很好 这是一个干净 可扩展的井字棋游戏 问题在于 TD 内的文本不会随比例缩放 有没有办法说 我希望文本大小为 TD 高度的 30 或者其他
  • Python 中 Javascript 的 reduce()、map() 和 filter() 的等价物是什么?

    Python 的等价物是什么 Javascript function wordParts currentPart lastPart return currentPart lastPart word Che mis try console l
  • jQuery 分钟和秒倒计时器

    我想创建一个 jquery 倒计时器 我尝试了以下代码 但它不起作用 我该怎么办 DEMO https jsfiddle net tbosn210 https jsfiddle net tbosn210 var interval setIn
  • ag-Grid 中的行格式

    我们需要有条件地将行文本设置为粗体 目前它仅适用于单个单元格 但我们需要在所有列单元格上应用文本粗体 应用格式设置后 isBold 列必须隐藏 删除 此列仅用于格式化 如何应用文本缩进 10px isBold 列包含真实值的第一列的 有可能
  • getCompatedStyle 类似于 IE8 的 javascript 函数

    我正在尝试在 Java GWT 代码中编写一个 Javascript 函数 该函数获取以下样式的值 direction fontFamily fontSize fontSizeAdjust fontStyle fontWeight lett
  • 将 html

    我有一些服务器端代码当前支持 http 字节范围请求 没有任何问题 但是 我希望能够在将转码后的块发送到客户端之前使用 ffmpeg 即时转码视频文件 位于磁盘上 但 ffmpeg 要求我在获取字节时给它一个寻道时间范围来自客户 给定客户端

随机推荐