Перенесення на рядок у JavaScript


184

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

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

DEMO

Усі вони дають однаковий вихід, але чи один з них кращий за інші?
Я б сказав, що + ""перевага має те, що вона рятує деяких персонажів, але це не така вже й велика перевага?


1
Мені здається, що якщо всі речі рівні, стандарт toString()був би таким шляхом.
asawyer

1
@asawyer. І чому це? Якщо всі вони дають однаковий результат і роблять те саме, виберіть один і перейдіть з ним. Це моя думка, якщо це дійсно так .
gdoron підтримує Моніку

1
Перші два методи повинні бути еквівалентними (ви повинні перевірити стандарт, але конструктор буде викликати toString). Третій НАЗАД виробляє однаковий вихід, але він включає дуже різний механізм (окрім швидкості, він включає різні виклики, тому це може бути не те, що ви очікуєте для кожного виду об'єктів).
Адріано Репетті

6
На мій погляд toString, семантично найясніший спосіб самостійно документувати той факт, що ви намагаєтеся отримати еквівалент рядка об'єкта. String(...)трохи тупий і value + ""трохи хак. Він також надає вам можливість змінити типовий стандарт toStringза допомогою спеціальної реалізації, якщо вам, напевно, потрібна незначна побічна перевага.
asawyer

2
@Adriano. Але + ""найшвидший за jsperf, так що ... я думаю, це робиться іншим чином.
gdoron підтримує Моніку

Відповіді:


213

Вони поводяться інакше, коли valueє null.

  • null.toString()видає помилку - Неможливо викликати метод 'toString' з null
  • String(null)повертає - "null"
  • null + ""також повертається - "null"

Дуже подібна поведінка трапляється, якщо valueє undefined(див . Відповідь jbabey ).

Крім цього, існує незначна різниця в продуктивності, яка, якщо ви не використовуєте їх у величезних циклах, не варто турбуватися.


Це насправді цікава різниця. Тож вам слід утриматися від використання, toString()коли ви ще не перевірили null.
Семмі С.

@SammyS. не знаю , якщо друк nullабо undefinedна екрані є більш бажаним поведінкою тоді Javascript помилки ...
Юстус Роміна

@JustusRomijn: Дійсно. Тим часом я почав використовувати тип Option для обробки таких помилок.
Семмі С.

ви можете перевірити будь-яку з цих викладених змінних з typeof, щоб перевірити наявність рядка. typeof (null + '') == 'string'
Брюс Лім

4
Є ще один випадок, коли вони поводяться по-різному. v + ''повертає невірний результат, якщо v має методи toString (), і valueOf (). Конкатенація буде ігнорувати toString () та використовуватиме valueOf (). Приклад класу, для якого не піддається
Мікіта Белахлазау

26

Існують відмінності, але вони, ймовірно, не стосуються вашого питання. Наприклад, прототип toString не існує на невизначених змінних, але ви можете надати невизначений рядок за допомогою двох інших методів:

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);кидає 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()повертає об’єкт не aString
gdoron підтримує Моніку

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

якщо у вас все з нульовим, невизначеним, NaN, 0 та неправдивим, усі кастинг на '', тоді (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значення (див. відповідь Connell Watkins)
  • 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) str - найповільнішим

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.