繁体   English   中英

JavaScript中的符号

[英]Symbol in Javascript

我在项目中看到了以下代码。 谁能解释这是怎么回事? 属性的价值是什么? 这是什么情况this[Attributes] = attrs行?

 const Attributes = Symbol('User#attrs');
    class User {   
      constructor (attrs) {
        this[Attributes] = attrs;
      }
    }

Symbol为任何对象创建一个不可识别的密钥:

const first = Symbol('debug-name');
const second = Symbol('debug-name');

first !== second // true;

const anObj = {};
anObj[first] = 123;
anObj[second] = 456;

console.log(anObj) // {Symbol('debug-name'): 123, Symbol('debug-name'): 456}

请注意,即使第firstsecond变量具有相同的调试字符串,它们也会在anObj创建不同的键。 有权first访问的任何人都可以将该密钥添加到任何对象,并且不会与该对象中的任何其他密钥冲突。

可以使用它代替魔术字符串来管理协议:

// ES5
someObject.MY_LIB_attributes = [1, 2, 3];
// Only safe if no other library uses the key
// "MY_LIB_attributes"

// ES2015+
export const Attributes = Symbol('myLib#attributes');

import { Attributes } from 'my-lib';

someObj[Attributes] = [1, 2, 3];
// Safe as long as no other library uses
// *this* Symbol instance for some other purpose.

编辑

由于您现在已经阐明了问题仅与代码行this[Attributes] = attrs ,请参阅我的答案的第二部分以进行讨论。

原始答案

这是ES6 Javascript的新功能。

  1. const Attributes = Symbol('User#attrs'); 创建一个新的Symbol对象。 这里描述符号功能和对象。 它创建一个唯一的标识符对象,然后可以将其用于许多其他用途,其中之一是用作属性名称。 新的符号功能上还有许多其他参考,因此在此不再赘述。

  2. class定义是用于声明原型类ES6方法 同样,在此新语法上还有许多其他参考,因此这里没有重复所有这些内容。 下面有一个等效ES5代码的示例。

  3. 这行this[Attributes] = attrs; 使用上面生成的符号在新创建的对象上设置属性。

类定义等效于常规的构造函数声明,如下所示:

function User(attrs) {
    this[Attributes] = attrs;
}

讨论this[Attributes] = attrs

Attributes是一个符号,可以用作对象上的属性名称。 这是生成可用作属性名称的唯一键的一种方式。 因此, this[Attributes] = attrs在新构造的对象上设置属性,并且使用Attributes符号作为属性名称。 Attributes符号是一个唯一值,不会与任何已知的字符串匹配(实际上,它甚至不会与其他Symbol对象匹配),因此这是制作唯一属性名称的一种方式。

目前尚不清楚代码为什么要这样做:

this[Attributes] = attrs;

而不是像这样:

this.attrs = attrs;

我们将不得不了解更多有关如何使用它的上下文,以及为什么不能使用纯字符串属性代替Symbol,因为您没有提供足够的上下文让我们知道。

一种可能的用途是保护隐私。 如果Attributes不是公开的,则这是一种在外界不知道如何访问的对象上创建属性的方法,因为必须具有Attributes的当前值才能正确访问该Attributes 正如您所展示的那样,在同一范围内具有UserAttributes的代码似乎不是私有的,但也许只有User导出到了公共范围。

另一个可能的用途是唯一性。 如果User对象可能通过其他代码添加了许多其他属性,则Attributes创建一个唯一的属性名称,该名称不能与其他属性名称冲突。 在这种情况下,这似乎不太可能,但这是使用符号的一种可能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM