Введение
Элементарные и ссылочные типы, или элементарно-ссылочный дуализм на примере строк в JavaScipt.
Одно из ключевых правил языка JavaScript состоит в особенностях выполнения операций над элементарными типами данных и ссылочными типами. Так, числа и логические величины являются элементарными типами данных, операции над ними выполняются по значению, они состоят из относительно небольшого и заранее определенного числа байт, поэтому операции над ними легко выполняются даже низкоуровневым интерпретатором JavaScript.
Примером ссылочных типов являются объекты. Что касается массивов и функций – они являются специализированными типами объектов, поэтому также представляют собой ссылочный тип данных. Эти типы данных характеризуются произвольным количеством свойств и элементов, поэтому операции над ними выполняются намного сложнее. В случае массивов и объектов больших размеров, операции по значению могут привести к избыточному копированию и сравнению огромных объемов памяти, что легко может поставить под сомнение оптимальность использования клиентских ресурсов.
Примером работы с элементарными типами послужит следующая пара инструкций:
var a = 5; // переменная с именем a хранит значение 5
var b = a; // производится операция копирования, исключительно по значению: переменная с именем b хранит другое значение 5 (его дубликат)
другим примером может послужить изменение значения внутренней копии переменной:
var a = a + 5; // эта строка изменяет только внутреннюю копию переменной с именем a, перезаписывая в нее значение 10
Что касается работы со ссылочными типами, простейшим примером послужит набор операций над двумя массивами:
var myArray = [10, 20, 30, 40]; // создаем переменную ссылочного типа, а именно массив с именем myArray состоящий из четырех элементов
var otherArray = myArray; // присваиваем новой переменной с именем otherArray первую перменную, при этом, копирование значений из переменной с именем myArray не производится, мы разрешаем новой переменной работать со значениями из первой.
otherArray[0] = 110; // так изменив якобы значения ново-созданной второй переменной, на самом деле мы производим операцию перезаписи значений из первой переменной.
alert(myArray); // отобразим значение 110,20,30,40
Стоит отметить, что строки, которые, на первый взгляд, могут восприняться в качестве ссылочного типа в силу неограниченности своей длины, что касается JavaScript, то строки зачастую рассматриваются с позиции элементарного типа из-за того, что не являются сущностью с природой объекта. Что же касается реальных случаев, то строки не могут вписываться в двойственный элементарно-ссылочный тип.
Строки нельзя представить объектами, поэтому можно предположить, что их можно отнести к элементарному типу, но такого рода ситуация может привести к непроизвольному расходованию системных ресурсов, в случае произведения операций по значению, в силу возможности задания произвольной длины строки. Поэтому в JavaScript нельзя изменить содержимое строки, пусть даже существует специальный метод charAt(), который после вызова вернет символ из заданной строки, но не существует метода setChartAt(), который мог бы ввести на это место другой символ. Строки в JavaScript преднамеренно созданы как неизменяемые сущности, в нем отсутствуют элементы языка, предполагающие возможность изменения символов в строке.
Видео курсы по схожей тематике:
Несмотря на то, что невозможно определить, каким образом производится копирование строк, есть возможность определить, как производится сравнение строк – по ссылке или же по их значению.
<script>
var row1 = "hello world";
var row2 = "hello " + "world";
if (row1 == row2) {
alert("строки сравниваются по значению")
}
script>
Поскольку мы сравниваем абсолютно разные строки, состоящие из одинаковых последовательностей символов, но они интерпретируются как эквивалентные, следовательно, увидим соответствующую надпись.
Важно помнить, что сравнение строк выполняется строго посимвольно и производится для числовых значений отдельного символа из общепринятой кодировки Unicode последовательно. Кроме того, сравнение символов происходит с учетом регистра, т.е. все прописные буквы будут иметь «вес» меньший, чем соответствующие строчные буквы.
var word1 = "hello";
var word2 = "Hello";
var rez = word1 < word2;
document.write(rez); // false
Также стоит помнить, что сравнение происходит от первого определения разных символов, при этом длина строки не учитывается
var word1 = "hello w";
var word2 = "hello World";
var rez = word1 > word2;
document.write(rez); // true
Порой получая знания от пользователя в виде строк, к примеру, используя prompt, возвращается строка, введенная пользователем. В таком случае нельзя сравнивать числа, полученные от пользователя, поскольку результат будет не верен.
var a = "5";
var b = "10";
var rez = a > b;
document.write(rez); // true
Бесплатные вебинары по схожей тематике:
Посимвольное сравнение дает результат: символ ‘5’ больше, чем ‘1’.
Стоит помнить о явном преобразовании полученных значений к числовым. Использую унарный знак плюс «+»
var a = "5";
var b = "10";
var rez = +a > +b;
document.write(rez); // false
Как видим, язык JavaScript имеет много тонкостей, о которых стоит помнить при написании своих сценариев и программ. В дальнейшем вы сможете самостоятельно обнаруживать подобные особенности и грамотно ими пользоваться.
Статьи по схожей тематике