-1

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;
      }
    }
3
  • 7
    Yes it is. This is valid javascript. Commented May 12, 2016 at 0:28
  • 1
    @nsdiv it is valid es6 code. Commented May 12, 2016 at 0:37
  • i don't know why i got good number of down votes for this question. Commented Jun 4, 2016 at 4:18

2 Answers 2

2

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.
Sign up to request clarification or add additional context in comments.

Comments

1

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.

5 Comments

Not a voter, but probably that you answered a broad and unclear question. It also doesn't fully cover what the code does or why it uses a symbol.
@AlexanderO'Mara - The question seemed very clear to me and it's hard to call something too broad that can be answered in four lines of text.
@AlexanderO'Mara While that's possible, it's also possible because this answer is primarily link-based, which is discouraged/disallowed on SO. It should non-trivially expand on the information presented in the link(s), or it would probably be better as a comment.
Well, I'm not sure you really covered what it is doing and why, but then I consider the scope of the question unclear. Again, not a voter.
The string argument to Symbol is only a debugging label. It does not effect the produced Symbol value in any way: Symbol('123') !== Symbol('123'). (I wasn't your downvoter either, by the way.)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.