Обратите внимание, что существует возможность (но в этом почти никогда нет необходимости или смысла) явно создавать объекты-обертки вызовом конструктора String(), Number()
или Boolean()
:
var s = "test", n = 1, b = true; // Строка, число и логическое значение,
var S = new String(s); // Объект String
var N = new Number(n); // Объект Number
var В = new Boolean(b); // Объект Boolean
При необходимости интерпретатор JavaScript обычно автоматически преобразует объекты-обертки, т. е. объекты S, N и В в примере выше, в обертываемые ими простые значения, но они не всегда ведут себя точно так же, как значения s, n и Ь. Оператор равенства ==
считает равными значения и соответствующие им объекты-обертки, но оператор идентичности ===
отличает их. Оператор typeof
также обнаруживает отличия между простыми значениями и их объектами-обертками.
3.7. Неизменяемые простые значения и ссылки на изменяемые объекты
Между простыми значениями ( undefined
, null
, логическими значениями, числами и строками) и объектами (включая массивы и функции) в языке JavaScript имеются фундаментальные отличия. Простые значения являются неизменяемыми: простое значение невозможно изменить (или «трансформировать»). Это очевидно для чисел и логических значений - нет никакого смысла изменять значение числа. Однако для строк это менее очевидно. Поскольку строки являются массивами символов, вполне естественно было бы ожидать наличие возможности изменять символы в той или иной позиции в строке. В действительности JavaScript не позволяет сделать это, и все строковые методы, которые, на первый взгляд, возвращают измененную строку, на самом деле возвращают новое строковое значение. Например:
var s = "hello"; // Изначально имеется некоторый текст из строчных символов
s.toUpperCase(); // Вернет "HELLO", но значение s при этом не изменится
s // =>» "hello": оригинальная строка не изменилась
Кроме того, величины простых типов сравниваются по значению: две величины считаются одинаковыми, если они имеют одно и то же значение. Для чисел, логических значений, null
и undefined
это выглядит очевидным: нет никакого другого способа сравнить их. Однако для строк это утверждение не выглядит таким очевидным. При сравнении двух строковых значений JavaScript считает их одинаковыми тогда и только тогда, когда они имеют одинаковую длину и содержат одинаковые символы в соответствующих позициях.
Объекты отличаются от простых типов. Во-первых, они являются изменяемыми - их значения можно изменять:
var о = { x:1 }; // Начальное значение объекта
о.x = 2; // Изменить, изменив значение свойства
о.у = 3; // Изменить, добавив новое свойство
var а = [1,2,3] // Массивы также являются изменяемыми объектами
а[0] = 0; // Изменить значение элемента массив
а[3] = 4; // Добавить новый элемент
Объекты не сравниваются по значению: два объекта не считаются равными, даже если они будут иметь одинаковые наборы свойств с одинаковыми значениями. И два массива не считаются равными, даже если они имеют один и тот же набор элементов, следующих в том же порядке:
var о = {х:1}, р = {х:1};// Два объекта с одинаковыми свойствами
о === р // => false: разные объекты не являются равными
var а = [], Ь = []; // Два различных пустых массива
а === b // => false: различные массивы не являются равными
Чтобы подчеркнуть отличие от простых типов JavaScript, объекты иногда называют ссылочными типами. Если следовать этой терминологии, значениями объектов являются ссылки, и можно сказать, что объекты сравниваются по ссылке: значения двух объектов считаются равными тогда и только тогда, когда они ссылаются на один и тот же объект в памяти.
var а = []; // Переменная а ссылается на пустой массив.
var b = а; // Теперь b ссылается на тот же массив.
Ь[0] = 1; // Изменение массива с помощью ссылки в переменной Ь.
а[0] // => 1: изменение можно наблюдать в переменной а.
а === b // => true: а и b ссылаются на один и тот же объект, поэтому они равны.
Как следует из примера выше, операция присваивания объекта (или массива) переменной фактически присваивает ссылку: она не создает новую копию объекта. Если в программе потребуется создать новую копию объекта или массива, необходимо будет явно скопировать свойства объекта или элементы массива. Следующий пример демонстрирует такое копирование с помощью цикла for (раздел 5.5.3):
Читать дальше
Конец ознакомительного отрывка
Купить книгу