What is the use of Symbol in javascript ECMAScript

2020-04-07 02:59发布

问题:

What is the use of Symbol in javascript (ECMASCRIPT6)?

Why does the example below return false?

const symbol1 = Symbol();

console.log(Symbol('foo') === Symbol('foo'));
// expected output: false

回答1:

Symbol is used to create a totally unique, one-of-a-kind identifier. It's use is precisely for the example you list.

Even if you call Symbol with the same string, the instances will be different. This allows different libraries (which may be used at the same time) to define keys which may be used at the same time.

For example, imagine two libraries using a common name to define something on window or global (or for illustration, the fake global door):

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

// your code
door.cake();

In this example, the first libraries code is lost because it was unintentionally given the same name as the first.

Now, if they both use Symbol, then even if they are named the same, you can still access both (assuming they export Symbol somehow):

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]();

Both are still accessible.

That is a bit of an oversimplification, but it illustrated the point.

In a more practical usage, these are used for things such as importing modules. The modules may end up with the same name, but that's okay because they'll have unique symbols associated with them, which makes them uniquely accessible as long as your have the Symbol objects.

As for when to use them yourself... it's probably going to be pretty rare. You'll mainly want to use them any time you have a way to provide the Symbol but need other things to remain unique. I've only used these directly in a few narrow circumstances where the created element may end up the same.

For example, if you were making an object using names as the key, you might have duplicate names. Without symbols, the objects would override one other. With symbols, they'll all remain.

const people = {};
people[Symbol('bob')] = { name: 'Bob Smith' };
people[Symbol('bob')] = { name: 'Bob Jones' };



回答2:

From the documentation:

Every symbol value returned from Symbol() is unique.

That means === comparisons will fail because they're not identical.

If you want a unique identifier of some sort that can be given a descriptive, if otherwise irrelevant name, then Symbol might be useful.



回答3:

The Idea of the symbol is to introduce private properties into Javascript. But, its actual purpose is for name collision.

Unfortunately, however, they ended up being severely downgraded, and not private after all, because you can find them via reflection. Specifically, via the Object.getOwnPropertySymbols method and through proxies.

Every symbol value returned from Symbol() is unique. A symbol value may be used as an identifier for object properties; this is the data type's only purpose. (as per mozilla)

var Pet = (function() {
  var typeSymbol = Symbol('type');
  function Pet(type) {
    this[typeSymbol] = type;
  }
  Pet.prototype.getType = function(){
    return this[typeSymbol];
  }
  return Pet;
}());

var a = new Pet('dog');
console.log(a.getType()); // prints dog
a[Object.getOwnPropertySymbols(a)[0]] = "cat"
console.log(a.getType()); //prints cat