Типы JavaScript

Согласно http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf, JavaScript имеет 6 типов: undefined, null, boolean, string, number и object.

var und;
console.log(typeof und); // <-- undefined

var n = null;
console.log(typeof n); // <--- **object**!

var b = true;
console.log(typeof b); // <-- boolean

var str = "myString"
console.log(typeof str); // <-- string

var int = 10;
console.log(typeof int); // <-- number

var obj = {}
console.log(typeof obj); // <-- object

Вопрос 1:

Почему null типа object вместо null?

Вопрос 2:

Что насчет функций?

var f = function() {};
console.log(typeof f); // <-- function

Переменная f имеет тип function. Почему он не указан в спецификации как отдельный тип?

Спасибо,


person Alex Ivasyuv    schedule 25.03.2010    source источник
comment
+1 за копание в спецификации в поисках целостного просветления.   -  person Ben Zotto    schedule 25.03.2010


Ответы (7)


Что касается typeof null == 'object', это ошибка, которая возникла с первых дней, и, к сожалению, эта ошибка останется с нами надолго, это было слишком поздно для исправления в спецификации ECMAScript 5th Edition.

Что касается функций, то это просто объекты, но у них есть особое внутреннее свойство с именем [[Call]], который используется внутри при вызове функции.

Оператор typeof различает простые объекты и функции, просто проверяя, объект имеет это внутреннее свойство.

person Christian C. Salvadó    schedule 25.03.2010

Это связано с тем, что typeof определено для возврата "объекта", если ввод null, и возврата "функции", если ввод доступен для вызова. (См. 11.4.3 Оператор typeof.)

Я не знаю, почему стандарт определен именно так (и Крокфорд сказал, что это неправильно). Возможно, обратная совместимость.

person kennytm    schedule 25.03.2010

Ответ на вопрос 1:

Свойство, когда оно не имеет определения, не определено. Причина, по которой null является объектом, заключается в том, что свойство может существовать без значения, но при этом иметь определение.

person Todd Moses    schedule 25.03.2010
comment
На самом деле я думаю, что это какое-то заблуждение. Есть разница между undefined и undeclared. Например, var x поместит свойство с именем x в текущую область, но его значение будет undefined. Прежде чем это произойдет, сам x не определен, и попытка его использования приведет к ошибке ReferenceError. - person bcherry; 25.03.2010
comment
Кроме того, null не является объектом, это примитивное значение, к сожалению, оператор typeof просто неверен... - person Christian C. Salvadó; 26.03.2010

typeof null === "object" потому что так написано в спецификации, но это ошибка самой первой версии JavaScript. (как говорит KennyTM выше).

typeof f === "function", потому что без try/catch нет другого надежного и надежного способа определить, является ли что-то вызываемым. Использование f.constructor === Function может работать, но я думаю, что это не гарантируется.

person bcherry    schedule 25.03.2010

Для полноты отметим, что в настоящее время лучший способ проверки информации о типе выглядит примерно так:

var typeInfo = Object.prototype.toString.call(yourObject);

Это дает вам строку, которая выглядит как «[object Something]», где «Something» — это имя типа.

person Community    schedule 25.03.2010
comment
Object.prototype.toString.call(undefined) дает мне [object Window] в Firefox o_O. - person kennytm; 25.03.2010
comment
KennyTM: Это потому, что когда null или undefined используются в качестве первого аргумента call или apply, контекст (ключевое слово this) внутри вызываемой функции будет установлен на глобальный объект. - person Christian C. Salvadó; 25.03.2010
comment
Правильно - если использовать эту технику, вы, вероятно, сначала выполните явный тест === для undefined - person Pointy; 25.03.2010

null — это специальное значение — оно не ложно, не 0, не пустая строка, не NaN или не определено.

null — это то, что вы получаете, когда ищете объект, которого там нет — не неопределенное свойство объекта, а саму вещь.

абзац с одним textNode вернет null для узлов nextSibling, регулярное выражение, которое не соответствует, возвращает null вместо массива и так далее.

может быть, у него должен быть свой тип, но тогда он начинает быть чем-то, чем-то с типом, а не отсутствием объекта.

person kennebec    schedule 25.03.2010

Существует также Array.prototype.

  • Объект.прототип
  • Массив.прототип
  • Функция.прототип
  • Номер.прототип
  • Строка.прототип
  • Boolean.prototype

Crockford запрещает использовать:

  • новый номер()
  • новая строка()
  • новый логический()
person Phillip Senn    schedule 10.05.2011