Javascript имеет множество "трюков" вокруг типов и типов конверсий, поэтому мне интересно, являются ли эти 2 метода одинаковыми или есть какой-то угловой случай, который делает их разными?
Какая разница между String (значение) vs value.toString()
Ответ 1
Они не полностью совпадают, и фактически конструктор 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
не является примитивным, перейдите к шагу 2, вернитеresult
- Если
- Если доступно, выполните метод
valueOf
.- Если
result
является примитивным, вернитеresult
, иначе Шаг 3.
- Если
- Throw
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"
// Now make the valueOf method also unavailable:
o.valueOf = null;
try {
String(o);
} catch (e) {
alert(e); // TypeError!
}
Если вы хотите больше использовать этот механизм, я бы рекомендовал вам взглянуть на ToPrimitive
и toString
внутренние операции.
Также я бы рекомендовал вам эту статью:
Ответ 2
value.toString()
приведет к ошибке, если value
имеет значение null. String(value)
не должен.
Например:
var value = null;
alert(value.toString());
будет терпеть неудачу, потому что value == null
.
var value = null;
alert(String(value));
должно отображать сообщение, читающее "null" (или подобное), но оно не сработает.
Ответ 3
String(value)
должен иметь тот же результат, что и value.toString()
в каждом случае, за исключением значений без таких свойств, как null
или undefined
. ''+value
даст тот же результат.
Ответ 4
String() [вызов конструктора] в основном вызывает .toString()
.toString() и String() можно вызывать на примитивных значениях (число, логическое значение, строка) и в основном ничего не делать:
true = > 'true'
false = > 'false'
17 = > '17'
'hello' = > 'hello'
Но, вызывающий эти функции на объектах, становится интересным:
если у объекта есть собственная функция .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(), определенный внутри объекта, будет вызываться, хотим ли мы обрабатывать объект в виде строки или как число