Меню

JavaScript: Преобразование типов данных

В JavaScript значения достаточно свободно (явно и неявно) могут быть преобразованы из одного типа в другой. Например, если какой-нибудь оператор ожидает получить значение определённого типа, а ему передаётся значение другого типа, то интерпретатор автоматически попытается выполнить преобразования к нужному типу:


console.log(10 + " машин");   // "10 машин". Число неявно преобразуется в строку
console.log('7' * '4');       // 28. Обе строки неявно преобразуются в числа

Неявное преобразование – это когда интерпретатор автоматически выполняет преобразование типов, т. е. без участия программиста. Явное преобразование – это когда преобразование выполняет сам программист. Явное преобразование иначе называют приведением типов:


console.log('7' * '4');                   // 28. Неявное преобразование
console.log(Number('7') * Number('4'));   // 28. Явное преобразование

В таблице ниже описывается, как в JavaScript выполняется преобразование значений из одного типа в другой. Пустые ячейки соответствуют ситуациям, когда преобразование не требуется:

Значение Преобразование в:
Строку Число Булево Объект
undefined
null
"undefined"
"null"
NaN
0
false
false
ошибка typeError
ошибка typeError
true
false
"true"
"false"
1
0
new Boolean(true)
new Boolean(false)
"" (пустая строка)
"1.2"
"one"
"-10"
"+10"
"011"
"0xff"
0
1.2
NaN
-10
10
11
255
false
true
true
true
true
true
true
new String("")
new String("1.2")
new String("one")
new String("-10")
new String("+10")
new String("011")
new String("0xff")
0
-0
NaN
Infinity
-Infinity
3
"0"
"0"
"NaN"
"Infinity"
"-Infinity"
"3"
false
false
false
true
true
true
new Number(0)
new Number(-0)
new Number(NaN)
new Number(Infinity)
new Number(-Infinity)
new Number(3)
{} (любой объект)

[] (пустой массив)
[9] (1 числовой элемент)
arr (любой другой массив)
function(){} (любая функция)
см. Преобразование объектов

""
"9"
см. Преобразование объектов
см. Преобразование объектов
см. Преобразование объектов
0
9
NaN
NaN
true

true
true
true
true

Для явного преобразования в простые типы используются следующие функции: Boolean(), Number(), String(). При неявном преобразования интерпретатор использует те же функции, что используются для явного преобразования.

Для явного преобразования можно использовать операторы вместо функций. Например, если один из операндов оператора + является строкой, то другой операнд также преобразуется в строку. Унарный оператор + преобразует свой операнд в число. Унарный оператор ! преобразует операнд в логическое значение и инвертирует его. Всё это стало причиной появления следующих своеобразных способов преобразования типов, которые можно встретить на практике:


x + ""  // То же, что и String(x)
+x      // То же, что и Number(x). Можно также встретить x - 0
!!х     // То же, что и Boolean(x)

Преобразование в числа

Функция Number() преобразует значения по следующим правилам:

  • Логические значения true и false преобразуются в 1 и 0 соответственно.
  • Числа возвращаются без изменения.
  • Значение null преобразуется в 0.
  • Значение undefined преобразуется в NaN.

Для строк действуют особые правила:

  • Если строка содержит только цифры с начальным знаком + или - либо без знака, она всегда преобразуется в целое десятичное число. Начальные нули игнорируются, например "0011" преобразуется в 11.
  • Если строка представляет собой число с плавающей точкой с начальным знаком + или - либо без знака, она преобразуется в соответствующее число с плавающей точкой (начальные нули также игнорируются).
  • Если строка представляет собой число в шестнадцатеричном формате, она преобразуется в соответствующее целое десятичное число.
  • Если строка пустая, она преобразуется в 0.
  • Если строка содержит что-то отличное от предыдущих вариантов, она преобразуется в NaN.
  • Для объектов вызывается метод valueOf(), а возвращаемое им значение автоматически преобразуется по предыдущим правилам. Если это преобразование даёт в результате NaN, вызывается метод toString() и применяются правила преобразования строк в числа.

Унарные операторы + и - работают по тем же правилам, что и функция Number().

Преобразование в булевы значения

Функция Boolean() преобразует значение в его логический эквивалент:

  • Следующие значения в результате преобразования дают значение false: undefined, null, 0, -0, NaN, "".
  • Значение false возвращается без изменения.
  • Все остальные значения в результате преобразования дают значение true.

Преобразование в строки

Функция String() преобразует значения по следующим правилам:

  • Для всех значений кроме null и undefined автоматически вызывается метод toString() и возвращается строковое представление значения.
  • Для значения null возвращается строка "null".
  • Для значения undefined возвращается строка "undefined".

Преобразование простых типов в объекты

Для преобразования простых значений в объекты используются конструкторы Boolean(), Number(), String():


var oNum = new Number(3);
var oStr = new String("1.2");
var oBool = new Boolean(true);

alert(typeof oNum);   // "object"
alert(typeof oStr);   // "object"
alert(typeof oBool);  // "object"

Преобразование объектов в простые значения

Все объекты наследуют два метода преобразования: toString() и valueOf().

Метод toString() возвращает строковое представление объекта. По умолчанию он ничего интересного не возвращает:


alert({x: 1}.toString());   // "[object Object]"

Некоторые типы имеют более специализированные версии метода toString(). Например, метод toString() у массива преобразует все его элементы в строки и затем объединяет их в одну строку, вставляя запятые между ними:


alert([1,2,3].toString());   // "1,2,3"

Задача метода valueOf() определена не так чётко: предполагается, что он должен преобразовать объект в представляющее его простое значение, если такое значение существует. Объекты по своей сути являются составными значениями, и большинство объектов не могут быть представлены в виде единственного простого значения, поэтому по умолчанию метод valueOf() возвращает не простое значение, а ссылку на него:


alert(typeof {x:2}.valueOf());   // "object"

При преобразовании объекта в строку интерпретатор JavaScript выполняет следующие действия:

  • Если объект имеет метод toString(), интерпретатор вызывает его. Если он возвращает простое значение, интерпретатор преобразует значение в строку (если оно не является строкой) и возвращает результат преобразования.
  • Если объект не имеет метода toString() или этот метод не возвращает простое значение, то интерпретатор проверяет наличие метода valueOf(). Если этот метод определён, интерпретатор вызывает его. Если он возвращает простое значение, интерпретатор преобразует это значение в строку (если оно не является строкой) и возвращает результат преобразования.
  • В противном случае интерпретатор делает вывод, что ни toString() ни valueOf() не позволяют получить простое значение и возбуждает ошибку TypeError.

При преобразовании объекта в число интерпретатор выполняет те же действия, но первым пытается применить метод valueOf():

  • Если объект имеет метод valueOf(), возвращающий простое значение, интерпретатор преобразует (при необходимости) это значение в число и возвращает результат.
  • Если объект не имеет метода valueOf() или этот метод не возвращает простое значение, то интерпретатор проверяет наличие метода toString(). Если объект имеет метод toString(), возвращающий простое значение, интерпретатор выполняет преобразование и возвращает полученное значение.
  • В противном случае интерпретатор делает вывод, что ни toString() ни valueOf() не позволяют получить простое значение и возбуждает ошибку TypeError.

Методы toString() и valueOf() доступны для чтения и записи, поэтому их можно переопределить и явно указать, что будет возвращаться при преобразовании:


var obj = {};
obj.toString = function() { return "объект"; };
alert("Это " + obj);   // "Это объект"

С этой темой смотрят: