Статья написана по мотивам бессмысленной и беспощадной дискуссии на javascript.ru.
Итак, есть у нас программа на языке JavaScript, в ней есть какие-то значения, а у значений есть какой-то тип. И вот вопрос: как нам узнать, этот самый тип значения?
И второй вопрос: а действительно ли нам надо его узнавать и нельзя ли обойтись другими средствами?
Под «типом» я здесь подразумеваю более широкое понятие, чем встроенный тип, возвращаемый оператором typeof
. Это, например, «массив» или «элемент DOM», которые для typeof
все на одно лицо ("object"
). Вернее их было бы назвать «классами типа object», но не будем пока погружаться в терминологию.
Когда знание типа не нужно
В большинстве случаев выяснять тип не требуется.
Если функция принимает в качестве аргумента HTMLDivElement с которым выполняет какие-то манипуляции и в документации к ней указана, что она принимает HTMLDivElement, то она может рассчитывать на то, что получит именно HTMLDivElement.
А если программист вызывает её со строкой в качестве аргумента, то это проблемы программиста. И проблемы в том самом месте, где он её вызывает.
Когда знание типа может пригодиться
При попытке же написать более универсальную функцию, знание типа (класса) переменных бывает не лишним.
Например, хотим мы создать функцию вроде map()
, которая перебирает элементы структуры, выполняет над ними какие-либо действия и возвращает аналогичную структуру, где вместо исходных элементов результаты этих действий. Или merge()
— рекурсивное слияние двух структур.
Здесь уже перебирать и сливать различные значения нужно по разному. Простые объекты через for (k in obj)
, массивы и подобные им (arguments
, HTMLCollection
) через for (i=0;i<len;i++)
. При этом Function
, например, тоже объект со своими свойствами, но при слиянии мы вправе ожидать, что скопируется сам объект функции, а не будут рекурсивно сливаться его свойства.
Для этого нам нужно знать, что перед нами — сугубо говоря, «словарь», «список» или «индивидуальный объект».
Остальной текст под катом