Home

Типы данных, преобразование типов

Содержание

1. Вступление

В компьютерном мире есть только данные. Можно читать данные, изменять данные, создавать новые – но кроме данных ничего нет. Все данные хранятся как длинные последовательности бит, этим они сходны между собой.

В процессе работы компьютерные программы манипулируют значениями, такими как число 3,14 или текст «Hello World». Типы значений, которые могут бытпредставлены и обработаны в языке программирования, известны как типы данных, и одной из наиболее фундаментальных характеристик любого языка программирования является поддерживаемый им набор типов данных.

Типы данных в JavaScript можно разделить на три категории: простые(примитивы), объект с его подтипами, и ECMAScript specification types(EST).

2. Примитивы

К категории примитивов в языке JavaScript относятся:

2.1 Числа

В отличие от многих языков программирования, в JavaScript не делается различий между целыми и вещественными значениями. Все числа в JavaScript представляются вещественными значениями (с плавающей точкой). Для представления чисел в JavaScript используется 64-битный формат, определяемый стандартом IEEE 754.

Обратите внимание, что любому числовому литералу может предшествовать знак «минус» (-), делающий числа отрицательными. Однако фактически минус представляет собой унарный оператор смены знака, не являющийся частью синтаксиса числовых литералов.

2.1.1 Числовые литералы

В JavaScript есть 4 числовых литералов:

Десятичный литерал

10; // 10
1.2; // 1.2
.2; // 0.2
1e+2; // 100
1e-2; // 0.01

Двоичный литерал с целыми числами

0b010101; // 21
0B010101; // 21

Восьмеричный целочисленный литерал

0o714; // 460
0O714; // 460

Шестнадцатеричный целочисленный литерал

0xFFAA; // 65450
0XFFAA; // 65450

2.1.2 Специальные числа

В JavaScript есть три специальных значения, которые считаются числами, но ведут себя не как обычные числа.

  • Infinity
  • -Infinity
  • NaN

2.1.2 NaN

Если математическая операция не может быть совершена, то возвращается специальное значение NaN (Not-A-Number).

Например, деление 0/0 в математическом смысле неопределено, поэтому его результат NaN.

'use strict';
alert( 0 / 0 ); // NaN

Значение NaN используется для обозначения математической ошибки и обладает следующими свойствами:

  • Значение NaN – единственное, в своем роде, которое не равно ничему, включая себя.

    'use strict';
    NaN == NaN // false
    
    'use strict';
    NaN === NaN // false
    
  • Значение NaN можно проверить специальной функцией isNaN(n), которая преобразует аргумент к числу и возвращает true.

    'use strict';
    alert(isNaN(5)); // false
    
    'use strict';
    alert(isNaN(NaN)); // true
    
  • Значение NaN «прилипчиво». Любая операция с NaN возвращает NaN.

    'use strict';
    alert( NaN + 1 ); // NaN
    

Никакие математические операции в JavaScript не могут привести к ошибке или «обрушить» программу. В худшем случае, результат будет NaN.

2.1.3 Infinity

Infinity – особенное численное значение, которое ведет себя в точности как математическая бесконечность ∞.

'use strict';
Infinity === Infinity // true
Infinity === -Infinity // false
Infinity > Infinity // false
Infinity > -Infinity // true
-Infinity < Infinity // true

2.1.4 Проверка на число

Глобальная isFinite() функция определяет, является ли переданное значение конечным числом. Если необходимо, параметр сначала преобразуется в число.

2.1.5 Методы объекта Number

<Number>.toPrecision()

Метод toPrecision() возвращает строку, представляющую объект Number с указанной точностью.

<Number>.toLocaleString()

Метод toLocaleString() возвращает строку с языко-зависимым представлением числа.

<Number>.toExponential

Метод toExponential() возвращает строку, представляющую объект Number в экспоненциальной записи.

<Number>.toFixed()

Метод toFixed() форматирует число, используя запись с фиксированной запятой.

2.2 Строки

Следующий базовый тип данных – строки. Строка – это неизменяемая, упорядоченная последовательность 16-битных значений, каждое из которых обычно представляет символ Юникода. Строки в JavaScript являются типом данных, используемым для представления текста. Длина строки – это количество 16-битных значений, содержащихся в ней. Нумерация символов в строках (и элементов в массивах) в языке JavaScript начинается с нуля: первое 16-битное значение находится в позиции 0, второе – в позиции 1 и т.д. Они используются для хранения текста. Записываются они в строковых литералах:

Пример

'use strict';
'This is my string';
"This is my string";
`This is my string`;

В ECMAScript 3 строковые литералы должны записываться в одной строке программы и не могут разбиваться на две строки. Однако в ECMAScript 5 строковые литералы можно разбивать на несколько строк, заканчивая каждую строку, кроме последней, символом обратного слэша (\). Ни один из символов обратного слэша, как и следующие за ними символы перевода строки, не будут включены в строковый литерал.

2.2.1 Экранирование символов

Если строка в одинарных кавычках, то внутренние одинарные кавычки внутри должны быть экранированы, то есть снабжены обратным слешем \', вот так:

Пример

'use strict';
'It\'s my string'; //It's my string
'This is my \"string\"'; //This is my "string"

"'It\'s my string"; //It's my string

`It's "string"`; // It's my string

2.2.2 Экранирование символов

Строки могут содержать специальные символы. Самый часто используемый из таких символов – это «перевод строки».

Пример

'use strict';
alert( 'Привет\nМир' ); // выведет "Мир" на новой строке

Есть и более редкие символы, вот их список:

  • \b
  • \t
  • \n
  • \v
  • \f
  • \r
  • \\
  • \'
  • \"

2.3 Логические значения

Логическое значение говорит об истинности или ложности чего-то. Логический тип данных имеет только два допустимых логических значения. Эти два значения представлены литералами true и false.

'use strict';
true;
false;

2.4 Cпециальный тип Null

В JavaScript null не является «ссылкой на несуществующий объект» или «нулевым указателем», как в некоторых других языках. Это просто специальное значение, которое имеет смысл «ничего» или «значение неизвестно».

2.5 Cпециальный тип undefined

В языке JavaScript имеется еще одно значение, свидетельствующее об отсутствии значения. Значение undefined, указывающее на полное отсутствие какого-либо значения. Оно возвращается при обращении к переменной, которой никогда не присваивалось значение, а также к несуществующему свойству объекта или элементу массива. Кроме того, значение undefined возвращается функциями, не имеющими возвращаемого значения, и присваивается параметрам функций для аргументов, которые не были переданы при вызове.

Идентификатор undefined является именем предопределенной глобальной переменной (а не ключевым словом, как null), которая инициализирована значением undefined. В ECMAScript 3 undefined является переменной, доступной для чтения/записи, которой можно присвоить любое другое значение. Эта проблема была исправлена в ECMAScript 5, и в реализациях JavaScript, соответствующих этому стандарту, переменная undefined доступна только для чтения.

Значение undefined можно рассматривать как признак неожиданного или ошибоч ного отсутствия какого-либо значения, а null – как признак обычного или вполне ожидаемого отсутствия значения. Если в программе потребуется присвоить одно из этих значений переменной или свойству или передать одно из этих значений функции, практически всегда предпочтительнее использовать значение null.

2.6 Cпециальный тип Symbol

Символы – новый примитивный тип, предназначенный для уникальных идентификаторов.

Основная область использования символов – это системные свойства объектов, которые задают разные аспекты их поведения. Поддержка у них пока небольшая, но она растёт. Системные символы позволяют разработчикам стандарта добавлять новые «особые» свойства объектов, при этом не резервируя соответствующие строковые значения.

3. Оператор typeof

Унарный оператор typeof помещается перед единственным операндом, который может иметь любой тип. Его значением является строка, указывающая на тип данных операнда.

'use strict';
typeof null; // "object"
typeof undefined; // "undefined" 
typeof Number(); // "number"
typeof String(); // "string"
typeof Boolean(); // "boolean"
typeof Symbol(); // "symbol"
typeof Object(); // "object"
typeof function() {} //"function"

У оператор typeof есть два синтаксиса: со скобками и без:

'use strict';
var x = null;
typeof x; // "object"
typeof(x); // "object" 

Работают они одинаково, но первый синтаксис короче.

4. Объектный тип данных

Объекты в языке JavaScript являются составными значениями(структурами): они представляют собой коллекции свойств, или именованных значений.

Объявляются объекты при помощи объектного литерала {}:

'use strict';
var a = {};

Свойство объекта так же также называют полем объекта. Поле объекта может хранить любой тип данных, включая функции, у таких свойст есть специальное название - метод.

Задать поле объекта можна через синтаксис ключ-значение внутри литерала объекта.

'use strict';
var a = {myKey : 0, mySecondKey: 5};

А получить доступ к полю можна с помощью такого синтаксиса:

'use strict';
var a = {myKey : 0, mySecondKey: 5};
console.log(a.mySecondKey);

5. Иммутабельность примитивов и ссылочность объектного типа

Между простыми значениями (undefined, null, boolean, числами, строками, символами) и объектами (включая массивы и функции) в языке JavaScript имеются фундаментальные отличия. Простые значения являются неизменяемыми (иммутабельными).

Простое значение невозможно изменить (трансформировать/модифицировать). Это очевидно для чисел и логических значений – нет никакого смысла изменять значение числа. Однако для строк это менее очевидно. Поскольку строки являются массивами символов, вполне естественно было бы ожидать наличие возможности изменять символы в той или иной позиции в строке. В действительности JavaScript не позволяет сделать это, и все строковые методы, которые, на первый взгляд, возвращают измененную строку, на самом деле возвращают новое строковое значение

Например:

'use strict';
var s = "hello"; // Из­на­чаль­но име­ет­ся не­ко­то­рый текст из строч­ных сим­во­лов
s.toUpperCase(); // Вер­нет "HELLO", но зна­че­ние s при этом не из­ме­нит­ся
console.log(s); // "hello": ори­ги­наль­ная стро­ка не из­ме­ни­лась

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

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

'use strict';
var o = {
    x : 1
}; // На­чаль­ное зна­че­ние объ­ек­та
o.x = 2; // Из­ме­нить, из­ме­нив зна­че­ние свой­ст­ва
o.y = 3; // Из­ме­нить, до­ба­вив но­вое свой­ст­во

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

'use strict';
var o = {x:1}, p = {x:1}; // Два объ­ек­та с оди­на­ко­вы­ми свой­ст­ва­ми
o === p; // false

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

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

Болие детально особенности объектного типа мы рассмотрим в последующих главах курса.

*. Упражнения

1. User

Создайте пустой объект user. Добавьте свойство name со значением Вася. Добавьте свойство surname со значением Петров. Поменяйте значение name на Сергей. Удалите свойство name из объекта.