Примитивные типы JavaScript и соответствующие объекты

В JavaScript не все данные являются объектами. Существует несколько примитивных типов, таких как строки, числа и логические значения, которые не являются объектами. Для каждого из этих типов существует конструктор, который выводит объект с похожим поведением: Number, String и Boolean. Чтобы запутать вещи, на самом деле можно вызывать методы примитивных типов - они будут преобразованы в соответствующие объекты во время этой операции, а затем преобразованы обратно. Например, можно сделать

var a = 4.1324;
a.toFixed(1) // Outputs 4.1

Тем не менее, если вы попытаетесь сравнить примитивные типы и объекты со строгим равенством, разница обнаружится

var a = new Number(4);
var b = 4;
a === b; // False!!!
typeof a; // 'object'
typeof b; // 'number'

На самом деле один из них пытается сравнить объекты, они все равно оказываются разными:

var a = new Number(4);
var b = new Number(4);
a === b; // False!!!

(С концептуальной точки зрения я как бы понимаю различие. Объекты могут иметь дополнительные свойства, поэтому они не должны сравниваться с равными, если они на самом деле не совпадают. Поэтому, если мы хотим иметь 4 === 4 нам нужно использовать тип, который не является объектом. Но эта дилемма стоит перед любым достаточно динамичным языком программирования, но я знаю только JavaScript, где есть два типа - один объектный и один нет - для чисел или строк.)

В чем преимущество сохранения двух отдельных представлений для чисел, строк и логических значений? В каком контексте может потребоваться различие между примитивными типами и объектами?

Ответ 1

В чем преимущество сохранения двух отдельных представлений для чисел, строк и логических значений?

Спектакль

В каком контексте может потребоваться различие между примитивными типами и объектами?

Принуждение приходит на ум. 0 == false а new Number(0) != false

Так, например:

var a = new Boolean(false);
if(a) {
  // This code runs
}

но

var a = false;
if(a) {
  // This code never runs
}

Вы можете прочитать больше о принуждении здесь: JavaScript Принуждение Демистифицировано

Ответ 2

В чем преимущество сохранения двух отдельных представлений?

Как вы указали, вы можете вызывать методы и для неупакованных значений (a.toFixed(1)). Но это вызывает преобразование. Другими словами, создание нового упакованного объекта (вероятно) каждый раз, когда вы вызываете такой метод.

Так что тут есть штраф за производительность. Если вы явно создаете номер в штучной упаковке и затем вызываете его методы, дальнейшие экземпляры создавать не нужно.

Так что я думаю, что причина того, что и то, и другое очень историческое. JavaScript начинался как простой интерпретируемый язык, что означало, что производительность была плохой, и имел в виду любой (простой) способ повышения производительности, такой как создание чисел и строк примитивными по умолчанию.

Java имеет упакованные и распакованные значения.