简体   繁体   中英

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?

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

Symbol creates an un-collidable key for any object:

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

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.

Original Answer

This is a couple of the new ES6 Javascript features.

  1. const Attributes = Symbol('User#attrs'); creates a new Symbol object. 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 . 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.

  3. This line 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

Attributes is a symbol which can be used as a property name on an object. 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 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.

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.

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

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. This seems less likely in this case, but it is one possible use of Symbols.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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