В JavaScript, как и в других языках программирования, имеется возможность манипулировать данными тремя способами.1 Первый способ – это копирование данных. Например, значение можно присвоить новой переменной. Второй спо_ соб – передать значение функции или методу. Третий – сравнить его с другим значением, чтобы проверить, равны ли эти значения. Для понимания языка программирования совершенно необходимо разобраться, как в нем выполняют_ ся эти три действия.
Существует два фундаментальных способа манипулирования данными: по зна' чению и по ссылке. Когда выполняется манипулирование данной величиной позначению, это означает, что в операции участвует собственно значение данной величины. В операции присваивания создается копия фактического значения, после чего эта копия сохраняется в переменной, в свойстве объекта или в эле_ менте массива. Копия и оригинал – это два совершенно независимых друг от друга значения, которые хранятся раздельно. Когда некоторая величина переда_ ется функции по значению, это означает, что функции передается копия. Если функция изменит полученное значение, эти изменения коснутся только копии и никак не затронут оригинал. Наконец, когда величина сравнивается по значе_ нию с другой величиной, два различных набора данных должны содержать одно
1 Этот раздел содержит достаточно сложный материал, который при первом про_ чтении можно пропустить.
62 Глава 3. Типы данных и значения
и то же значение (это обычно подразумевает, что для выявления эквивалентно_ сти величин производится их побайтное сравнение).
Другой способ манипулирования значением – по ссылке. В этом случае сущест_ вует только одна фактическая копия значения, а манипулирование производит_ ся посредством ссылок на это значение.1 Когда действия со значением произво_ дятся по ссылке, переменные хранят не само значение, а лишь ссылки на него. Именно эта ссылочная информация копируется, передается и участвует в опера_ циях сравнения. Таким образом, в операции присваивания по ссылке участвует сама ссылка, а не копия значения и не само значение. После присваивания пере_ менная будет ссылаться на то же самое значение, что и оригинальная перемен_ ная. Обе ссылки считаются абсолютно равноправными и в равной степени могут использоваться для манипулирования значением. Если значение изменяется с помощью одной ссылки, эти изменения будут наблюдаться с помощью другой ссылки. То же происходит, когда значение передается функции по ссылке. В функцию попадает ссылка на значение, а функция может использовать ее для изменения самого значения. Любые такие изменения становятся видимыми за пределами функции. Наконец, когда выполняется операция сравнения по ссыл_ ке, происходит сравнение двух ссылок, чтобы проверить, не ссылаются ли они на одно и то же значение. Ссылки на два разных значения, даже эквивалентные (т. е. состоящие из тех же самых байтов данных), не могут считаться равными.
Это два абсолютно разных способа манипулирования значениями, и разобраться в них совершенно необходимо. В табл. 3.4 приводится краткое описание выше_ изложенного. Данная дискуссия, посвященная манипулированию данными по ссылке и по значению, носила достаточно общий характер, но она с небольшими отличиями вполне применима ко всем языкам программирования. В следую_ щих разделах описываются характерные отличия, свойственные языку Java_ Script. Там рассказывается о том, какими типами данных манипулировать по значению, а какими – по ссылке.
Таблица 3.4. Передача данных по ссылке и по значению
По значению
По ссылке
Копирова_
Выполняется копирование
Копируется только ссылка на значение.
ние
самого значения – образуют_
Если значение будет изменено с помощью
ся две независимые друг от
вновь созданной копии ссылки, эти изме_
друга копии.
нения будут наблюдаться при использо_
вании оригинальной ссылки.
Передача
Функции передается отдель_
Функции передается ссылка на значение.
ная копия значения. Измене_
Если внутри функции значение будет из_
ние этой копии не оказывает
менено с помощью полученной ссылки,
никакого влияния на значе_
эти изменения будут наблюдаться и за ее
ние за пределами функции.
пределами.
1 Программисты на C и все те, кому знакома концепция указателей, должны пони_ мать основную идею ссылок в данном контексте. Тем не менее следует отметить, что JavaScript не поддерживает работу с указателями.