简体   繁体   English

JavaScript中的符号

[英]Symbol in Javascript

I saw following code in a project. 我在项目中看到了以下代码。 can anyone explain what is going on here? 谁能解释这是怎么回事? What will be value of Attributes? 属性的价值是什么? What is happening this[Attributes] = attrs line? 这是什么情况this[Attributes] = attrs行?

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

Symbol creates an un-collidable key for any object: 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}

Note that even though the first and second variables have the same debugging string they create different keys in anObj . 请注意,即使第firstsecond变量具有相同的调试字符串,它们也会在anObj创建不同的键。 Anyone who has access to first can add that key to any object and it will not collide with any other key in that object. 有权first访问的任何人都可以将该密钥添加到任何对象,并且不会与该对象中的任何其他密钥冲突。

This can be used instead of magic strings to manage protocols: 可以使用它代替魔术字符串来管理协议:

// 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.

Edit 编辑

Since you've now clarified the question to be only about the line of code this[Attributes] = attrs , see the second part of my answer for discussion of that. 由于您现在已经阐明了问题仅与代码行this[Attributes] = attrs ,请参阅我的答案的第二部分以进行讨论。

Original Answer 原始答案

This is a couple of the new ES6 Javascript features. 这是ES6 Javascript的新功能。

  1. const Attributes = Symbol('User#attrs'); creates a new Symbol object. 创建一个新的Symbol对象。 The Symbol function and object is described here . 这里描述符号功能和对象。 It creates a unique identifier object that can then be used for many other uses, one of which is as a property name. 它创建一个唯一的标识符对象,然后可以将其用于许多其他用途,其中之一是用作属性名称。 There are many other references on the new Symbol feature so I won't repeat all of that here. 新的符号功能上还有许多其他参考,因此在此不再赘述。

  2. The class definition is the ES6 method for declaring prototyped classes . class定义是用于声明原型类ES6方法 Again, there are many other references on this new syntax so there is no point in repeating all that here. 同样,在此新语法上还有许多其他参考,因此这里没有重复所有这些内容。 There's an example below of what the equivalent ES5 code is. 下面有一个等效ES5代码的示例。

  3. This line this[Attributes] = attrs; 这行this[Attributes] = attrs; uses the Symbol generated above to set a property on the newly created object. 使用上面生成的符号在新创建的对象上设置属性。

The class definition is equivalent to the regular constructor declaration like this: 类定义等效于常规的构造函数声明,如下所示:

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

Discussion of this[Attributes] = attrs 讨论this[Attributes] = attrs

Attributes is a symbol which can be used as a property name on an object. Attributes是一个符号,可以用作对象上的属性名称。 It's a way of generating a unique key that can be used as a property name. 这是生成可用作属性名称的唯一键的一种方式。 So, this[Attributes] = attrs is setting a property on the newly constructed object and it is using the Attributes symbol as the property name. 因此, this[Attributes] = attrs在新构造的对象上设置属性,并且使用Attributes符号作为属性名称。 This Attributes symbol is a unique value that will not match any known string (in fact it won't even match other Symbol objects) so it's a way of making a unique property name. Attributes符号是一个唯一值,不会与任何已知的字符串匹配(实际上,它甚至不会与其他Symbol对象匹配),因此这是制作唯一属性名称的一种方式。

It is unclear why the code does this: 目前尚不清楚代码为什么要这样做:

this[Attributes] = attrs;

instead of just something like this: 而不是像这样:

this.attrs = attrs;

We would have to see a bit more context for how that is being used and why a plain string property could not also be used in place of the Symbol as you haven't provided enough context for us to know. 我们将不得不了解更多有关如何使用它的上下文,以及为什么不能使用纯字符串属性代替Symbol,因为您没有提供足够的上下文让我们知道。

One possible use is for privacy. 一种可能的用途是保护隐私。 If Attributes is not public, then this is a way of creating a property on the object that the outside world doesn't know how to access because you have to have the current value of Attributes in order to access that properly. 如果Attributes不是公开的,则这是一种在外界不知道如何访问的对象上创建属性的方法,因为必须具有Attributes的当前值才能正确访问该Attributes As you've shown the code with User and Attributes in the same scope that does not seem like it is private, but perhaps only User is exported to a public scope. 正如您所展示的那样,在同一范围内具有UserAttributes的代码似乎不是私有的,但也许只有User导出到了公共范围。

Another possible use is for uniqueness. 另一个可能的用途是唯一性。 If the User object may have lots of other properties added to it by other code, then Attributes creates a unique property name that cannot collide with other property names. 如果User对象可能通过其他代码添加了许多其他属性,则Attributes创建一个唯一的属性名称,该名称不能与其他属性名称冲突。 This seems less likely in this case, but it is one possible use of Symbols. 在这种情况下,这似乎不太可能,但这是使用符号的一种可能。

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

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