Відповіді:
Вони не зовсім однакові, і насправді конструктор String, який називається функцією (ваш перший приклад), в кінці буде називати toStringпереданий метод об'єкта, наприклад:
var o = { toString: function () { return "foo"; } };
String(o); // "foo"
З іншого боку, якщо ідентифікатор посилається на, nullабо undefinedви не можете використовувати toStringметод, він дасть вам TypeErrorвиняток :
var value = null;
String(null); // "null"
value.toString(); // TypeError
StringКонструктор викликається як функція буде приблизно еквівалентно:
value + '';
Правила перетворення типів з Object -to- Primitive детально описані у специфікації, [[DefaultValue]]внутрішній операції.
Коротко підсумовані, при перетворенні з Object -to- String здійснюються наступні кроки:
toStringметод.
resultце примітивно , повернення result, інакше перехід до кроку 2.valueOfметод.
resultце примітивно , повернення result, інакше перейти до кроку 3.TypeError.Враховуючи вищезазначені правила, ми можемо зробити приклад включеної семантики:
var o = {
toString: function () { return "foo"; },
valueOf: function () { return "bar"; }
};
String(o); // "foo"
// Make the toString method unavailable:
o.toString = null;
String(o); // "bar"
// Also make the valueOf method unavailable:
o.valueOf = null;
try {
String(o);
} catch (e) {
alert(e); // TypeError
}
Якщо ви хочете дізнатися більше про цей механізм, я рекомендую ознайомитися ToPrimitiveз ToStringвнутрішніми операціями.
Я також рекомендую прочитати цю статтю:
new String({toString: null})кидає а TypeError.
String()і + ''зараз є досить значна різниця. String(Symbol())запуститься, але Symbol() + ''видасть помилку (і Symbol () передасть захист фальси, на відміну від нульового та невизначеного, тому x && (x + '')тепер може кинути).
value.toString()призведе до помилки, якщо вона valueє нульовою. String(value)не повинен.
Наприклад:
var value = null;
alert(value.toString());
не вдасться, тому що value == null.
var value = null;
alert(String(value));
повинно відображатися повідомлення з написом "null" (або подібне), але воно не вийде з ладу.
String () [ виклик конструктора ] в основному викликає .toString ()
.toString () і String () можна викликати примітивні значення (число, булеві, рядкові) і в основному нічого особливого не будуть робити:
true => 'true'
false => 'false'
17 => '17'
'привіт' => 'привіт'
Але виклик цих функцій на об’єктах - це те, що стає цікавим:
якщо в об'єкта є своя функція .toString (), він буде викликаний, коли коли-небудь вам потрібно буде розглядати цей об'єкт як рядок (явно / неявно)
let obj = {
myName:"some object",
toString:function(){ return this.myName; }
}
//implicitly treating this obj as a string
"hello " + obj; //"hello some object"
//OR (explicitly)
"hello " + String(obj) //calling the existent toString function
//OR
"hello " + obj.toString(); //calling toString directly
До речі, якщо ви хочете розглянути цей об'єкт як число, він повинен мати в ньому функцію .valueOf () .
що робити, якщо ми обидва в одному об’єкті?
якщо ми хочемо трактувати цей об'єкт як рядок => використовувати .toString ()
якщо ми хочемо трактувати цей об’єкт як число => використовувати .valueOf ()
що робити, якщо у нас визначено лише .valueOf () ?
.valueOf (), визначений всередині об'єкта, буде називатися, чи хочемо ми обробляти об'єкт як рядок або як число
new String(value)за будь-якого значення, він завжди поверне рядковий об'єкт.