Подтвердить что ты не робот

Какая разница между String (значение) vs value.toString()

Javascript имеет множество "трюков" вокруг типов и типов конверсий, поэтому мне интересно, являются ли эти 2 метода одинаковыми или есть какой-то угловой случай, который делает их разными?

4b9b3361

Ответ 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(), определенный внутри объекта, будет вызываться, хотим ли мы обрабатывать объект в виде строки или как число