Типы данных в Javascript (особенности)

7 октября 2010 г.

Данная статья предназначена для WebUI программистов, или людей работающих с JS кодом, которые хотят полностью разобраться с особенностью типов данных JS.
Согласно 5-той редакции ECMAscript (http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf стр. 28) существует 6 типов данных:
undefined, null, Boolean, String, Number,Object.
Прежде чем мы приступим, обращая внимание что в JS существует два типа сравнения:
== — два знака
=== — три знака
разница между ними в том, что первый вариант делает сравнение типов данных с приведением типа,
в то время как второй — без приведение типа. То есть выходить, что
второй вариант проверяет и тип и значение, в то время как первый
вариант проверяет лишь значение.

Итак, продолжим. Начнем с двух типов данных которые наибольшие «конфюзят» разработчиков: undefined и null.
undefined и null грубо говоря чем-то похожи между собой, ну хотя бы тем, что оба они предназначены для отображения чего-то неопределенного или несуществующего.
Рассмотрим такой пример:
undefined == null; // true
Заметьте, что сдесь мы применили два знака равно. Но на самом деле, undefined и null это разные вещи:
undefined === null; // false
Теперь я попытаюсь объяснить, зачем же было придумано два типа, вроде делающих одно и то же.
Давайте начнем с того, что такое вообще undefined. Это тип данных, который означает не определенный (не установленный).
Такой тип данных очень легко получить, просто объявив переменную.
var a; // undefined
или
var a = undefined; // то же самое

typeof a; // undefined
Как видно с примера, если значение равняется undefined, это значит что переменная существует (иначе было бы исключение ReferenceError), но она не определена никаким значением, соответственно у нее автоматически стает тип undefined. Все предельно просто. Так зачем же тогда null? Это мы увидим дальше…
Согласно ECMAscript спецификации, если мы обращаемся к несуществующему ключу объекта, мы должны получить undefined.

var o = {
x: 1,
y: 2
};
o.z; // undefined
typeof o.z; // undefined

Тут все просто, нету ключа, возвращается undefined.
Но как же быть если у меня ключ есть, а тип как раз undefined?

var o = {
x: 1,
y: 2,
z: undefined
};
o.z; // undefined
typeof o.z; // undefined

Как мы видим результат один и тот же.
Вот тут на и поможет null.

var o = {
x: 1,
y: 2,
z: null
};
o.z; // null
typeof o.z; // object <-- опа!

Как видим, null нам помог в том, чтобы явно указать что ключ существует, но с типом null.
Вообще-то более культурным способом проверки ключа в объекте является «in»
"z" in o; // true
В не зависимости от того будет ключ стоять в undefined или null он вернет true.
Так зачем же тогда null? Риторический вопрос. Хорошим тоном программирования является использовать undefined для простых типов, а null для объектов. Если в ответ я получаю null, это значит что предо мной будущий объект. Если же я получаю undefined это должно было быть какое-то значение, либо string либо number.
Это не аксиома но правила хорошего тона.
А теперь интересные примеры:

undefined == null; // true
!!undefined == !!null; // true
!!undefined == false; // true
!!undefined == 0; // true
undefined == false; // false
"undefined" == undefined; // false
!!undefined + null + 0; // 0

И так подведем итоги. undefined — создан для указания неопределенного типа данных (то есть фактически без типа), в то время как null для указания несуществующей ссылки или объекта.
В предыдущем примере можно было заметить, что null
определился как объект. Это бага JS которая тянется с ранних версий. Ее
уже не фиксают, чтобы не ломать совместимость с предыдущими версиями.
Теперь еще один интересный случай. function.
function f(){}
typeof f; // function <– вот это да
Оказывается есть еще тип данных как ф-ция? Нет. На самом деле ф-ция является объектом с импламентнутым методом Call.

var a = [];
typeof a; // object

Вот тут все OK. Массив и на самом деле является объектом. В то время
как объект в некотором роде можно рассматривать как ассоциативный
массив.
bclary.com/2004/11/07/#a-13.2.1
bclary.com/2004/11/07/#a-11.4.3
javascript.crockford.com/remedial.html
wiki.ecmascript.org/doku.php?id=proposals:typeof

 

Теги: рубрика JavaScript
  • Похожие статьи
  • Предыдущие из рубрики