2015-11-08 3 views
2

Я работаю над приложением ES6, которое отправляет некоторые данные по сети. Часть этого включает идентификаторы, которые реализованы как ES6 Symbol s. Например:Могу ли я полагаться на строковое представление символа ES6 `Symbol`?

const FOO = Symbol('foo'); 

Вызов Foo.toString() урожайности Symbol(foo). Когда я передаю их по сети, я хотел бы передать это как foo. Однако, насколько мне известно, нет способа извлечь foo из Symbol(foo), кроме как вытащить его с помощью регулярного выражения (в частности, /^Symbol\((.*)\)$/).

Должен ли я полагаться на регулярное выражение, всегда соответствующее? Или возможно, что будущие обновления ES6 нарушат это? Если я не могу полагаться на соответствие регулярному выражению, я просто отправлю его по проводу как Symbol(foo).

+0

Какое регулярное выражение, которое вы хотели бы предложить? – Xufox

+0

Предлагаем '/^Символ \ ((. *) \) $ /' (Затем используя первую группу захвата в качестве имени). Добавлен вопрос. –

+1

В соответствии с [spec] (http://www.ecma-international.org/ecma-262/6.0/#sec-symbol.prototype.tostring) это всегда символ «Символ» («+ описание +») ». Вероятно, вам лучше использовать 'FOO.toString(). Slice (7, -1)', потому что описание символа может содержать круглые скобки, разрывы строк и т. Д. Например, '.' не соответствует разрыву строк. – Xufox

ответ

4

В соответствии с spec это всегда "Symbol(" + description + ")".

Symbol.prototype.toString возвращает строку из внутреннего вызова метода к SymbolDescriptiveString(sym):

Пусть убывание быть SYM «s [[Description]] значение.
If desc is undefined, let desc be be string string.
[...]
Возвращает результат конкатенации строк "Symbol(", убывание и ")".

Вы, вероятно, лучше использовать

FOO.toString().slice(7, -1) 

, потому что описание символа сама может содержать скобки, разрывы строк и т.д. . в регулярном выражении не будет соответствовать разрывы строк, например.

3

Единственное, что нужно добавить в ответ @Xufox, это то, что Symbol.prototype.toString может быть скомпрометирован (перезаписан), и в этом случае он может вернуть что-то еще. Учитывая, что это вряд ли сценарий, который вам нужно/нужно учитывать, все должно быть хорошо; перейти на .toString().slice(7, -1);.


Альтернативным решением, которое вы, возможно, захотите рассмотреть, было бы использование глобального символа. Если вы собираетесь передавать свои данные, и вам будет необходимо предотвратить конфликты имен, это будет подходящим вариантом использования (если вы не пишете библиотеку, которая должна использоваться третьими лицами).

Вы бы использовать

const FOO = Symbol.for("foo"); 
//     ^^^ 

, а затем может получить имя символа (который также является его описание) обратно через

Symbol.keyFor(FOO) // "foo" 
+0

Это нормально, но не работает, если у вас должны быть отдельные символы с их описанием, заданным как «foo», так как все присваивания, сделанные 'Symbol.for (« foo »), будут присваивать один и тот же символ. – Redu

+0

@Redu Вот в чем их глобальность, да. Вам нужно будет выбрать 'foo' тщательно. – Bergi

Смежные вопросы