Вы не знаете JS: типы данных и значения
Здесь приводятся выдержки из книги Кайла Симпсона You Don’t Know JS Type&Grammar, переведенные на русский язык и фрагменты кода с комментариями. Надеюсь, кому-нибудь это поможет, лучше понять JavaScript. Ну а я смогу лучше систематизировать свои знания и использовать их на практике.
Типы данных.
Встроенные типы
С точки зрения JavaScript, тип — это набор характеристик значения, который отличает поведение одного типа значения от другого. Другими словами, если вы планируете использовать 42 как число, значит, тип данных для этого значения будет числом (number).
JavaScript определяет 7 типов данных:
- null
- undefined
- boolean
- string
- number
- object
- symbol (добавлен в ES6)
Все типы данных кроме объектов (objects) — примитивные. Оператор typeof() возвращает тип данных для значения в виде строки. Во всех случаях оператор typeof будет возвращать верное значение из списка кроме null. В случае с null оператор typeof вернет object. Это баг языка JavaScript. Несмотря на то, что при проверке typeof, null вернет “object”, при преобразовании в тип boolean null вернет false.
Седьмой тип данных, который может вернуть typeof — “function”:
typeof function a() < /* .. */ >=== "function"; // true
Массивы также имеют тип данных object, потому что фактически массивы и есть объекты с той лишь разницей, что свойства массива являются нумерованными индексами.
typeof [1,2,3] === “object”; // true
Значения как типы данных
В JavaScript у переменных нет типа — тип есть у значений. Переменные же могут содержать любое значение в любое время. В одном случае это может быть число (number), в другом — строка (string) и т.д..
Undefined vs undeclared.
Для переменных, которые были объявлены, но не были инициализированы тип данных вернет undefined.
var a;
typeof a; // "undefined"
var b = 42;
var c;
// later
b = c;
typeof b; // "undefined"
typeof c; // "undefined"
В данном случае, переменная была объявлена, но на текущий момент, внутри переменной не хранится никакого значения. В случае, если переменная не была объявлена (undeclared) возникнет ошибка, однако при этом оператор typeof для undeclared переменной вернет undefined:
var a;
a; // undefined
b; // ReferenceError: b is not defined
typeof(b); //undefined
Эта фича typeof является защитной т.к. в этом случае можно проверить переменную на undeclared без возникновения ReferenceError.
Значения.
Массивы.
Если сравнивать со строго типизированными языками программирования в JavaScript массивы всего лишь контейнеры для любых типов значений: от строки(string), числа(number), до объекта(object), или даже другого массива (array):
var a = [ 1, "2", [3] ];a.length; //3
a[0] === 1; // true
a[2][0] === 3; //true
Нет необходимости заранее определять размер массива, можно лишь объявить его и добавлять элементы по мере необходимости.
Будьте осторожны при создании массивов с пустыми ячейками.
var a = [ ];a[0] = 1;
//ячейка a[1] пуста
a[2]=[ 3 ];a[1]; //undefined
a.length //3
Такой код может привести к странному поведению с пустыми ячейками, оставленными между элементами массива. Ячейка появляясь получает значение undefined, но ведет себя не совсем также как ячейка, которой undefined присвоено в явном виде.
Ячейки массива имеют числовые индексы (как мы обычно и ожидаем), но хитрость в том что массивы также являются объектами и могут иметь свойство в виде строки ключ/значение, которое не будет считаться при подсчете размера массива в свойстве .length
Как бы там ни было всегда есть риск попасться в ловушку, когда строковое значение, изначально предполагаемое как ключ будет сконвертировано в число:
var a = [ ];a["13"] = 42;a.length; // 14
Так что, для хранения ключ/свойство нужно использовать объекты, а для хранения значений в строго нумерованных ячейках — массивы.
Массивоподобные.
Различные операции по поиску элементов DOM возвращают список DOM элементов, которые являются массивоподобной коллекцией значений с нумерованными индексами. Поэтому, есть возможность конвертации массивоподобного значения в настоящий массив и применения методов массива (таких как indexOf(..), concat(..), forEach(..) и т.д.). Другой пример — когда функция представляет аргументы в виде массивоподобного объекта, для доступа к аргументам, как к списку значений.
Строки.
Есть распространенное мнение, что строки всего лишь массивы из символов. Важно понимать, что строки и массивы символов — не одно и то же. Строки имеют поверхностное сходство с массивами для них работают свойство .length, методы .indexOf() .concat().
Однако, строки в JavaScript неизменяемы, тогда как массивы могут меняться. Для строки нет методов, которые меняют ее содержимое на месте, метод лучше создаст новую строку и вернет ее нам.
Можно “одалживать” методы массивов которые не требуют изменения строки по месту либо конвертировать строку в массив каждый раз когда это понадобится.
Это просто невозможно. В JS, даже если все 10 разных ссылок ведут к одному значению, ни одна из них не будет являться ссылкой для другой.
Простые величины null, undefined, string, number, boolean, и ES6’s symbol всегда копируются по значению.
Сложные величины объекты (в том числе массивы) и функции всегда копируются по ссылке.
Мы не можем контролировать как будет происходить копирование — по значению или по ссылке.
Это обусловлено типом значения с которым мы работаем.
Типы данных в JavaScript
Всего в JavaScript, существует 6 типов данных:
— Число number ,
— Строка string ,
— Логический (булев) тип данных boolean ,
— Отсутствие значения undefined ,
— Пустота, ничто null ,
— Объект object .
Эти 6 типов данных, делятся на два вида, простые типы данных и составные (объектные) типы данных.
Простые (примитивные) типы данных: number, string, boolean, undefined, null.
Составные (объектные) типы данных: object
Составным типом данных являются: объект, функция, массив (см. в конце статьи).
Прежде чем рассмотреть каждый тип данных, познакомимся сначала с оператором typeof . Данный оператор позволяет узнать, какой тип данных у переменной, делается это так:
var имяПеременной; имяПеременной = значение; alert(typeof имяПеременной);
Тип данных: number
Number — тип данных число. Числа могут быть как целыми так и с плавающей запятой (дробные, вещественные, действительные числа).
var myNumber = 5; var myNumber2 = 5.5;
В JavaScript в числах с плавающей запятой, используются точки, а не запятые
Проверяем с помощью оператора typeof, тип данных наших переменных:
alert(typeof myNumber); alert(typeof myNumber2);
В обоих случаях, скрипт выдаст нам сообщение number .
Тип данных: string
String — тип данных строка. Чтобы превратить значение переменной в строку, её нужно обрамить кавычками: дойными «строка» или одинарными ‘строка’. Если число обрамить кавычками, то её тип данных из number превратится в string :
var myString = 'Привет я строка JavaScript'; var myString2 = '5';
Проверяем с помощью оператора typeof, тип данных наших переменных:
alert(typeof myString); alert(typeof myString2);
В обоих случаях скрипт выдаст нам сообщение string .
Тип данных: boolean
Boolean — логический (булев) тип данных, он может иметь только одно их двух значений: true (правда) или false (ложь). Значения true или false обычно появляются в операциях сравнения или логических операциях.
var myBoolean = true; var myBoolean2 = false;
Проверяем с помощью оператора typeof, тип данных наших переменных:
alert(typeof myBoolean); alert(typeof myBoolean2);
В обоих случаях, скрипт выдаст нам сообщение boolean .
Если логический тип данных обрамить кавычками, то его тип данных из boolean превратится в string.
Тип данных: undefined
Undefined — тип данных который имеет всего одно значение undefined . Этот тип данных появляется тогда, когда переменная объявлена, но не инициализирована, т.е. когда у переменной (свойства объекта или элемента массива) отсутствует значение.
// Объявили переменную, но не присвоили ей значенияvar myUndefined;// Проверяем с помощью оператора typeof, тип данных нашей переменнойalert(typeof myUndefined);
Функция alert() выдаст нам сообщение undefined .
Если переменной присвоить значение undefined , то её тип данных тоже будет undefined .
var myUndefined2 = undefined; alert(typeof myUndefined2);
Если значение undefined обрамить кавычками, то его тип данных из undefined превратится в string.
Тип данных: object
Object — тип данных объект.
var myObject; myObject = < svoistvo: "znachenie", svoistvo2: "znachenie2", >;
Проверяем с помощью оператора typeof, тип данных нашего объекта:
alert(typeof myObject);
Скрипт выдаст нам сообщение object . Так же оператор typeof, покажет object у массивов и функций (см. ниже).
Тип данных: null
Null — это специальный тип данных обозначающий пустоту (ничего). Null — это специальный пустой объект. Например null может появиться при нажатии на кнопку отмена при использовании функции promt().
var myNull = null; alert(typeof myNull);
Данный скрипт выдаст сообщение object , почему так происходит читайте ниже.
Если null обрамить кавычками, то его тип данных из null превратится в string.
Уточнение по работе с оператором typeof
Здесь сообщу о некоторых подводных камнях которые есть в операторе typeof, например при работе с null и с функциями он выдаёт не верный тип данных, что часто путает начинающих. Ниже я составил небольшую табличку, показывающую как работает оператор typeof:
typeof 7; // number typeof "Строка"; // string typeof true; // boolean typeof undefined; // undefined typeof <>; // object typeof []; // object typeof null; // object typeof new Array(); // object typeof function()<>; // function typeof function имяФункции()<> // function
Хотя на самом деле, null это null , а функция это object .
typeof возвращает нам не тип данных, а строку зависящую от аргумента и не являющуюся именем типа. —>
Вместо new Array() можно вcтавить любой другой конструктор объектов, например new Date() или new RegExp() .
