Какая польза от Символ в JavaScript (ECMASCRIPT6)?
Почему в приведенном ниже примере возвращается false?
const symbol1 = Symbol();
console.info(Symbol('foo') === Symbol('foo'));
// expected output: false
@Bergi lol, хорошая находка, теперь я понятия не имею, на что я отвечал здесь и собирал данные для своего ответа на этот вопрос, не замечая, что на него уже ответили. Этот вопрос, вероятно, должен получить более удобный заголовок (отредактировал заголовок этого вопроса)
@nicael Вы все равно можете удалить свой (хороший!) ответ здесь и опубликовать его там для большей аудитории
@Bergi Готово, спасибо за предложение.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


От документация:
Every symbol value returned from
Symbol()is unique.
Это означает, что сравнения === не удастся, потому что они не идентичный.
Если вам нужен какой-то уникальный идентификатор, которому можно дать описательное, если в противном случае неуместное имя, то может быть полезен Symbol.
хорошо, но какой толк и когда нам нужен символ в javascript,
Это можно использовать там, где вам нужен уникальный идентификатор, такой как UUID, но вы не заботитесь ни о деталях реализации, ни о содержимом.
Symbol используется для создания полностью уникального, единственного в своем роде идентификатора. Это использование именно для приведенного вами примера.
Даже если вы вызовете Symbol с той же строкой, экземпляры будут разными. Это позволяет различным библиотекам (которые могут использоваться одновременно) определять ключи, которые могут использоваться одновременно.
Например, представьте две библиотеки, использующие общее имя для определения чего-либо на window или global (или, для иллюстрации, поддельном глобальном door):
const door = {};
// from library 1
door.cake = () => console.info('chocolate');
// from library 2
door.cake = () => console.info('vanilla');
// your code
door.cake();В этом примере код первой библиотеки потерян, потому что ему случайно было присвоено то же имя, что и первой.
Теперь, если они оба используют Symbol, то даже если они названы одинаково, вы все равно можете получить доступ к обоим (при условии, что они каким-то образом экспортируют Symbol):
const door = {};
// library 1
const cake1 = Symbol('cake');
door[cake1] = () => console.info('chocolate');
// library 2
const cake2 = Symbol('cake');
door[cake2] = () => console.info('vanilla');
// your code
door[cake1]();
door[cake2]();Оба по-прежнему доступны.
Это немного упрощает, но иллюстрирует суть.
В более практическом использовании они используются для таких вещей, как импорт модулей. Модули могут иметь одно и то же имя, но это нормально, потому что с ними будут связаны уникальные символы, что делает их однозначно доступными, пока у вас есть объекты Symbol.
Что касается того, когда использовать их самостоятельно ... это, вероятно, будет довольно редко. В основном вы захотите использовать их каждый раз, когда у вас есть способ предоставить Symbol, но вам нужны другие вещи, чтобы оставаться уникальными. Я использовал их напрямую только в нескольких узких случаях, когда созданный элемент может оказаться таким же.
Например, если вы создавали объект, используя имена в качестве ключа, у вас могут быть повторяющиеся имена. Без символов объекты перекрывали бы друг друга. С символами все они останутся.
const people = {};
people[Symbol('bob')] = { name: 'Bob Smith' };
people[Symbol('bob')] = { name: 'Bob Jones' };Я пытался задать вопрос на stackoverflow.com/questions/59768559/…, и мне сказали, что это дубликат этого. Единственное, что заставляет ваш код работать, - это потому, что cake1 и cake2 имеют разные имена, но они были назначены разработчиком. Как Symbol помогает в этой ситуации? Если вы переименовали cake1 и cake2 в cake, вы получите сообщение об ошибке, потому что это не уникальный. Если предполагается, что Symbol решит эту уникальную проблему, то, похоже, здесь он не помогает.
Вы получаете значения для использования в качестве ключей, перепутанных с именами переменных. Вы не можете повторно объявить одно и то же имя переменной в той же области (и не должны), если используете let или const. Однако это не имеет ничего общего с Symbol. Символ должен гарантировать, что каждый раз, когда вы звоните Symbol, вы получаете полностью уникальный идентификатор, не важно что. «То же самое», что я установил, было Symbol('cake') для показа обоих, хотя я создал два символа с одинаковым именем (или «описанием», как, вероятно, называется параметр), он генерирует два уникальных символа. Когда вы используете их в качестве ключей к объектам, они относятся к двум разным вещам.
Идея символа - ввести частные свойства в Javascript. Но на самом деле его цель - конфликт имен.
К сожалению, однако, они в конечном итоге были сильно понижены в рейтинге и в конце концов перестали быть личными, потому что вы можете найти их с помощью отражения. В частности, через метод Object.getOwnPropertySymbols и через прокси.
Каждое значение символа, возвращаемое функцией Symbol (), уникально. Значение символа может использоваться как идентификатор для свойств объекта; это единственное назначение типа данных. (согласно 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.info(a.getType()); // prints dog
a[Object.getOwnPropertySymbols(a)[0]] = "cat"
console.info(a.getType()); //prints cat
Это один из возможных вариантов использования, хотя я не думаю, что он был движущей силой. Это было больше для того, чтобы иметь дело с разными источниками кода, перекрывающими друг друга.
Документы MDN довольно ясны: «Каждое значение символа, возвращаемое функцией Symbol (), уникально».