JavaScript. Подробное руководство, 6-е издание, стр. 25

Обратите внимание, что существует возможность (но в этом почти никогда нет необходимости или смысла) явно создавать объекты-обертки вызовом конструктора

<b>String(), Number()</b>
или
<b>Boolean()</b>
:

<b>var s = &quot;test&quot;, n = 1, b = true; // Строка, число и логическое значение,</b>

<b>var S = new String(s);  // Объект String</b>

<b>var N = new Number(n);  // Объект Number</b>

<b>var В = new Boolean(b); // Объект Boolean</b>

При необходимости интерпретатор JavaScript обычно автоматически преобразует объекты-обертки, т. е. объекты S, N и В в примере выше, в обертываемые ими простые значения, но они не всегда ведут себя точно так же, как значения s, n и Ь. Оператор равенства

<b>==</b>
считает равными значения и соответствующие им объекты-обертки, но оператор идентичности
<b>===</b>
отличает их. Оператор
<b>typeof</b>
также обнаруживает отличия между простыми значениями и их объектами-обертками.

3.7. Неизменяемые простые значения и ссылки на изменяемые объекты

Между простыми значениями (

<b>undefined</b>
,
<b>null</b>
, логическими значениями, числами и строками) и объектами (включая массивы и функции) в языке JavaScript имеются фундаментальные отличия. Простые значения являются неизменяемыми: простое значение невозможно изменить (или «трансформировать»). Это очевидно для чисел и логических значений - нет никакого смысла изменять значение числа. Однако для строк это менее очевидно. Поскольку строки являются массивами символов, вполне естественно было бы ожидать наличие возможности изменять символы в той или иной позиции в строке. В действительности JavaScript не позволяет сделать это, и все строковые методы, которые, на первый взгляд, возвращают измененную строку, на самом деле возвращают новое строковое значение. Например:

<b>var s = &quot;hello&quot;; // Изначально имеется некоторый текст из строчных символов </b>

<b>s.toUpperCase(); // Вернет &quot;HELLO&quot;, но значение s при этом не изменится </b>

<b>s // =&gt;» &quot;hello&quot;: оригинальная строка не изменилась</b>

Кроме того, величины простых типов сравниваются по значению: две величины считаются одинаковыми, если они имеют одно и то же значение. Для чисел, логических значений,

<b>null</b>
и
<b>undefined</b>
это выглядит очевидным: нет никакого другого способа сравнить их. Однако для строк это утверждение не выглядит таким очевидным. При сравнении двух строковых значений JavaScript считает их одинаковыми тогда и только тогда, когда они имеют одинаковую длину и содержат одинаковые символы в соответствующих позициях.

Объекты отличаются от простых типов. Во-первых, они являются изменяемыми - их значения можно изменять:

<b>var о = { x:1 }; // Начальное значение объекта</b>

<b>о.x = 2;         // Изменить, изменив значение свойства</b>

<b>о.у = 3;         // Изменить, добавив новое свойство</b>

<b>var а = [1,2,3]  // Массивы также являются изменяемыми объектами</b>

<b>а[0] = 0;        // Изменить значение элемента массив</b>

<b>а[3] = 4;        // Добавить новый элемент</b>

Объекты не сравниваются по значению: два объекта не считаются равными, даже если они будут иметь одинаковые наборы свойств с одинаковыми значениями. И два массива не считаются равными, даже если они имеют один и тот же набор элементов, следующих в том же порядке:

<b>var о = {х:1}, р = {х:1};// Два объекта с одинаковыми свойствами</b>

<b>о === р          // =&gt; false: разные объекты не являются равными</b>

<b>var а = [], Ь = [];      // Два различных пустых массива  </b>

<b>а === b          // =&gt; false: различные массивы не являются равными</b>

Чтобы подчеркнуть отличие от простых типов JavaScript, объекты иногда называют ссылочными типами. Если следовать этой терминологии, значениями объектов являются ссылки, и можно сказать, что объекты сравниваются по ссылке: значения двух объектов считаются равными тогда и только тогда, когда они ссылаются на один и тот же объект в памяти.

<b>var а = []; // Переменная а ссылается на пустой массив.</b>

<b>var b = а;  // Теперь b ссылается на тот же массив.</b>

<b>Ь[0] = 1;   // Изменение массива с помощью ссылки в переменной Ь.</b>

<b>а[0]        // =&gt; 1: изменение можно наблюдать в переменной а.</b>

<b>а === b     // =&gt; true: а и b ссылаются на один и тот же объект, поэтому они равны.</b>

Как следует из примера выше, операция присваивания объекта (или массива) переменной фактически присваивает ссылку: она не создает новую копию объекта. Если в программе потребуется создать новую копию объекта или массива, необходимо будет явно скопировать свойства объекта или элементы массива. Следующий пример демонстрирует такое копирование с помощью цикла for (раздел 5.5.3):

<b>var a=['a<sup>,</sup>,<sup>,</sup>b<sup>,</sup>,'c’]; // Копируемый массив</b>

<b>var b = []; // Массив, куда выполняется копирование</b>

<b>for(var і = 0; і &lt; a.length; i++) { // Для каждого элемента в массиве а[]</b>

<b>  b[і] = а[і]; // Скопировать элемент а[] в b[]</b>

<b>}</b>

Точно так же, если потребуется сравнить два отдельных объекта или массива, необходимо будет сравнить значения их свойств или элементов. Ниже приводится определение функции, сравнивающей два массива:

<b>function equalArrays(a, b) {</b>

<b>  if (a.length != b.length) return false; // Массивы разной длины не равны </b>