Как в JS узнать что объект — массив?

Узнал на семинаре Кантора такую штуку. Как узнать, что объект, который пришёл на вход — массив? Конечно, лучше использовать утиную типизацию, но если нам нужен именно массив, со всей полнотой методов, не проверять же каждый?

Кстати, если кто-то думает, что ответ «typeof», то он просто не знает JS. Эта конструкция вернёт «object».

Я до недавнего времени думал, что правильный способ такой:
console.log([] instanceof Array); // true
А редко его используют, потому что конструкция «instanceof» не везде реализована. Я заблуждался. Вот правильный способ:
console.log(Object.prototype.toString.call([]) == '[object Array]'); // true
И вот почему. Оказывается, у каждого фрейма своя иерархия типов, если один фрейм передаёт во второй какой-то объект, то «instanceof» даст «false», так как сравнивает c «Array», локальным для этого фрейма. Проблему иллюстрирует следующий пример:
<script>
function Up(arr, iframeWindow) {
    alert(arr instanceof Array); // false
    alert(arr instanceof iframeWindow.Array); // true

    alert(Object.prototype.toString.call([]) == '[object Array]'); // true
}
</script>
<iframe src="data:text/html, <script>parent.Up([], window)</script>"></iframe>
28 апреля 2012 18:14

Александр Бабаев (bealex.moikrug.ru)
28 апреля 2012, 21:33

вспомнилось

if (Boolean.valueOf(stringValue).length() == 4) {
// stringValue is "true" :)
}

bolk (bolknote.ru)
28 апреля 2012, 21:58, ответ предназначен Александр Бабаев (bealex.moikrug.ru):

Хехе :)

Только «Boolean.valueOf.call(stringValue).length», наверное :) И на «null» оно тоже «4» вернёт. И на «1234» — тоже.

PastorGL (инкогнито)
28 апреля 2012, 22:01

Оказывается, у каждого фрейма своя иерархия типов
Знатная подлянка. Между контекстами JS можно безопасно передавать только во что-нибудь сериализованные объекты, и пересоздавать их на принимающей стороне заново.
Я на ней однажды, давным-давно, ещё во времена IE 5.5, потерял кучу времени. Приложение у меня было многофреймовое, JSON'а тогда ещё не было, и пришлось здорово поизвращаться.

Александр Бабаев (bealex.moikrug.ru)
29 апреля 2012, 00:00, ответ предназначен bolk (bolknote.ru):

А я не говорил, что это корректный код. Это кусок какого-то индусского программирования. Напомнило не в смысле также круто, просто ассоциация :)

Imfo.ru (инкогнито)
29 апреля 2012, 13:05

Array.isArray, не везде, правда.

bolk (bolknote.ru)
29 апреля 2012, 16:12, ответ предназначен Imfo.ru

Ну это что-то совсем не везде.

ixth (инкогнито)
29 апреля 2012, 21:42

Всегда недолюбливал этот метод. Насколько помню, то, что отдает Array при приведении к строке - vendor-specific и никто не гарантирует, что в какой-нибудь среде эта строка не будет другой. Хотя, isArray в jQuery использует именно этот метод, как достаточно надежный.

ixth (инкогнито)
29 апреля 2012, 23:25

Куда более изящно выглядит такой способ: [].constructor.name, но в средах, где он поддерживается, скорее всего есть и isArray.

bolk (bolknote.ru)
30 апреля 2012, 09:49, ответ предназначен ixth

Всегда недолюбливал этот метод. Насколько помню, то, что отдает Array при приведении к строке - vendor-specific и никто не гарантирует, что в какой-нибудь среде эта строка не будет другой.
Насколько я знаю, напротив, в стандарте закреплено, что строка будет именно такой.

ixth (инкогнито)
30 апреля 2012, 19:21, ответ предназначен bolk (bolknote.ru):

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

Морозов (morozov.livejournal.com)
1 мая 2012, 08:19

Интересно, а почему тогда конструкция "[1,2,3].toString()" возвращает строку "1,2,3"? Судя по описанной логике, при приведении массива к строке тоже должно было получиться "[object Array]".

bolk (bolknote.ru)
1 мая 2012, 10:21, ответ предназначен Морозов (morozov.livejournal.com):

Она возвращает сроку, потому что метод toString у массива возвращает строку элементов через запятую. Где вы увидели, что должно быть иначе?

Морозов (morozov.livejournal.com)
21 мая 2012, 12:14

Ну да, не заметил. Используется Object.prototype.toString, а не Array.prototype.toString

alshur (инкогнито)
2 июня 2012, 01:06, ответ предназначен bolk (bolknote.ru):

Узнал на семинаре Кантора такую штуку
я полагал, что Кантор должен к тебе ходить на семинары ;-)

bolk (bolknote.ru)
2 июня 2012, 08:12, ответ предназначен alshur

Я же не всё на свете знаю :) Но кое-что новое я ему рассказал, полагаю :)

Ваше имя или адрес блога (можно OpenID):

Текст вашего комментария, не HTML:

Кому бы вы хотели ответить (или кликните на его аватару)