В Javascript есть много "хитростей" вокруг типов и преобразований типов, поэтому мне интересно, одинаковы ли эти 2 метода или есть какой-то угловой случай, который их отличает?
источник
В Javascript есть много "хитростей" вокруг типов и преобразований типов, поэтому мне интересно, одинаковы ли эти 2 метода или есть какой-то угловой случай, который их отличает?
Они не полностью одинаковы, и на самом деле конструктор 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 + '';
Правила преобразования типа от объекта -До- Примитивными подробно описано описаны на спецификации, на [[DefaultValue]]
внутренней операции.
Кратко, при преобразовании из Объекта -До- строки , выполняются следующие шаги:
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(value)
при любом значении он всегда будет возвращать строковый объект.new String({toString: null})
бросаетTypeError
.String()
и+ ''
теперь есть довольно существенная разница.String(Symbol())
будет работать, ноSymbol() + ''
выдаст ошибку (и Symbol () передаст ложную охрану, в отличие от null и undefined, поэтомуx && (x + '')
теперь может вызывать ).value.toString()
вызовет ошибку, еслиvalue
имеет значение null.String(value)
не должна.Например:
потерпит неудачу, потому что
value == null
.должен отображать сообщение, читающее "null" (или подобное), но не произойдет сбой.
источник
String(value)
должен иметь тот же результат, что иvalue.toString()
в любом случае, за исключением значений без таких свойств, какnull
илиundefined
.''+value
даст тот же результат.источник
String () [ вызов конструктора ] в основном вызывает .toString ()
.toString () и String () могут вызываться для примитивных значений (число, логическое значение, строка) и в основном ничего особенного делать не будут:
Но при вызове этих функций для объектов все становится интересно:
если у объекта есть собственная функция .toString (), она будет вызываться, когда вам понадобится, чтобы этот объект обрабатывался как строка (явно / неявно)
Кстати, если вы хотите рассматривать этот объект как число, в нем должна быть определена функция .valueOf () .
что, если у нас есть только .valueOf () ?
.valueOf (), определенный внутри объекта, будет вызываться независимо от того, хотим ли мы обработать объект как строку или как число.
источник