Приведение к строке в JavaScript


184

Я нашел три способа приведения переменной Stringв JavaScript.
Я искал эти три опции в исходном коде jQuery, и все они используются .
Я хотел бы знать, есть ли различия между ними:

value.toString()
String(value)
value + ""

DEMO

Все они производят один и тот же результат, но один из них лучше других?
Я бы сказал, что у + ""него есть преимущество в том, что он сохраняет некоторых персонажей, но это не такое большое преимущество, что-нибудь еще?


1
Мне кажется, что если все вещи равны, стандарт toString()будет путь.
asawyer

1
@asawyer. И почему так? Если все они производят одинаковый результат и делают то же самое, выберите один и продолжайте. Это мое мнение, если это действительно так .
Гдорон поддерживает Монику

1
Первые два метода должны быть эквивалентны (вы должны проверить стандарт, но конструктор вызовет toString). Третий, как правило, выдает тот же результат, но включает в себя совершенно другой механизм (кроме скорости, он включает в себя различные вызовы, поэтому он может быть не тем, что вы ожидаете для каждого типа объекта).
Адриано Репетти

6
На мой взгляд toString, семантически это самый простой способ документировать сам факт того, что вы пытаетесь получить строковый эквивалент объекта. String(...)немного тупой, и value + ""немного взломать. Это также дает вам возможность переопределить настройки по умолчанию toStringс пользовательской реализацией, если вы когда-либо нуждались, я полагаю, в качестве незначительной дополнительной выгоды.
asawyer

2
@Adriano. Но + ""он самый быстрый в соответствии с jsperf, так что ... он делает это иначе, я думаю.
Гдорон поддерживает Монику

Ответы:


213

Они ведут себя по-разному, когда valueесть null.

  • null.toString()выдает ошибку - Невозможно вызвать метод 'toString' с нулевым значением
  • String(null)возвращает - «ноль»
  • null + ""также возвращает - «ноль»

Очень похожее поведение происходит, если valueесть undefined(см . Ответ JBabey ).

Кроме этого, есть незначительная разница в производительности, о которой, если вы не используете их в больших циклах, не стоит беспокоиться.


Это на самом деле интересная разница. Поэтому вы должны воздерживаться от использования, toString()когда вы еще не проверили null.
Сэмми С.

@SammyS. не знаю, является ли печать nullили undefinedвывод на экран более желательным поведением, чем ошибка javascript ...
Юстус Ромийн

@JustusRomijn: Да, действительно. Тем временем я начал использовать тип Option для обработки таких ошибок.
Сэмми С.

Вы можете проверить любую из этих приведенных переменных с typeof, чтобы проверить строку. typeof (null + '') == 'string'
Брюс Лим

4
Есть еще один случай, когда они ведут себя по-другому. v + ''возвращает неверный результат, если v имеет методы toString () и valueOf (). Конкатенация будет игнорировать toString () и будет использовать valueOf (). Пример класса, для которого конкатенация не удалась: github.com/processing-js/processing-js/blob/…
Никита Белахлазау

26

Есть различия, но они, вероятно, не имеют отношения к вашему вопросу. Например, прототип toString не существует для неопределенных переменных, но вы можете привести undefined к строке, используя два других метода:

var foo;

var myString1 = String(foo); // "undefined" as a string

var myString2 = foo + ''; // "undefined" as a string

var myString3 = foo.toString(); // throws an exception

http://jsfiddle.net/f8YwA/


3
Если переменная вообще не определена, вы все равно получите ошибку для String(). Пример: String(test);throws Uncaught ReferenceError: test is not defined, в то время как var test; String(test);приведет к "undefined".
Энтони

17

Они ведут себя одинаково, но toStringтакже предоставляют способ преобразования двоичных, восьмеричных или шестнадцатеричных строк:

Пример:

var a = (50274).toString(16)  // "c462"
var b = (76).toString(8)      // "114"
var c = (7623).toString(36)   // "5vr"
var d = (100).toString(2)     // "1100100"

9

Согласно этому тесту JSPerf , они отличаются по скорости. Но если вы не собираетесь использовать их в огромных количествах, любой из них должен работать хорошо.

Для полноты: как уже упоминалось asawyer , вы также можете использовать .toString()метод.


2
У этого jsperf один и тот же тест дважды, я его отредактировал и new String()возвращает объект, который неString
Гдорон поддерживает Монику

new String()возвращает объект да. String()Однако возвращает строку, которая является в вопросе.
Коннелл

2
Это не совсем правда. Как видно из результатов, конкатенация пустой строки и объекта не дает того же результата, что и конкатенация объекта и пустой строки. Кроме того, new String(blarg)дает вам Stringобъект, который вы можете вызвать toString(). В моем отладчике Chrome они фактически приводят к тому же виду объектов, за исключением упомянутой разницы.
Сэмми С.

@SammyS. Не могли бы вы добавить пример результатов производительности к вашему ответу? Ссылка на jsperf в настоящее время не работает и, безусловно, будет снова через 5 лет.
mxmlnkn

9

В дополнение ко всему вышесказанному следует отметить, что для определенного значения v:

  • String(v) звонки v.toString()
  • '' + vвызовы v.valueOf()до любого другого типа приведения

Таким образом, мы могли бы сделать что-то вроде:

var mixin = {
  valueOf:  function () { return false },
  toString: function () { return 'true' }
};
mixin === false;  // false
mixin == false;    // true
'' + mixin;       // "false"
String(mixin)     // "true"

Протестировано в FF 34.0 и Node 0.10


8

если вы согласны с null, undefined, NaN, 0 и false, все приведение к '' тогда (s ? s+'' : '')будет быстрее.

см. http://jsperf.com/cast-to-string/8

обратите внимание - в настоящее время существуют значительные различия между браузерами.


4

Реальный пример: У меня есть функция журнала , которая может быть вызвана с произвольным числом параметров: log("foo is {} and bar is {}", param1, param2). Если установлен DEBUGфлаг true, скобки заменяются данными параметрами, и строка передается console.log(msg). Параметрами могут быть и будут строки, числа и все, что может быть возвращено вызовами JSON / AJAX, может быть даже null.

  • arguments[i].toString()это не вариант из-за возможных nullзначений (см. ответ Коннелла Уоткинса)
  • JSLint будет жаловаться arguments[i] + "". Это может или не может повлиять на решение о том, что использовать. Некоторые люди строго придерживаются JSLint.
  • В некоторых браузерах конкатенация пустых строк выполняется немного быстрее, чем использование строковой функции или строкового конструктора (см. Тест JSPerf в ответе Sammys S.). В Opera 12 и Firefox 19 конкатенация пустых строк выполняется быстрее (95% в Firefox 19), или, по крайней мере, JSPerf так говорит.

1

На этой странице вы можете самостоятельно проверить производительность каждого метода :)

http://jsperf.com/cast-to-string/2

здесь, на всех машинах и браузерах, ' "" + str ' самый быстрый, (String) самый медленный

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.