Как эффективно проверить, является ли переменная Array или Object (в NodeJS & V8)? - PullRequest
40 голосов
/ 12 января 2012

Есть ли способ эффективно проверить, является ли переменная Object или Array, в NodeJS & V8?

Я пишу модель для MongoDB и NodeJS, и для обхода дерева объектов мне нужно знать, является ли объект простым (Number, String, ...) или составным (Hash, Array).

Кажется, что V8 имеет быструю встроенную Array.isArray, но как проверить, является ли объект Объектом? Я имею в виду сложный объект, такой как хэш {} или экземпляр класса, а не что-то вроде new String()?

Обычно это можно сделать так:

Object.prototype.toString.call(object) == "[object Object]"

или это:

object === Object(object)

Но похоже, что эти операции недешевы, может быть, есть и более эффективные? Это нормально, если он не универсален и не работает на всех двигателях, он нужен мне только для V8.

Ответы [ 13 ]

1 голос
/ 12 января 2012

глядя на jQuery они там jQuery.isArray(...) они делают:

    isArray = Array.isArray || function( obj ) {
    return jQuery.type(obj) === "array";
}

это приводит нас к: jQuery.type:

    type = function( obj ) {
    return obj == null ?
        String( obj ) :
        class2type[ toString.call(obj) ] || "object";
}

и снова мы должны посмотретьclass2type

class2type = {};

// Populate the class2type map
jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
    class2type[ "[object " + name + "]" ] = name.toLowerCase();
});

и в нативном JS:

var a, t = "Boolean Number String Function Array Date RegExp Object".split(" ");
for( a in t ) {
    class2type[ "[object " + t[a] + "]" ] = t[a].toLowerCase();
}

это заканчивается:

var isArray = Array.isArray || function( obj ) {
    return toString.call(obj) === "[object Array]";
}
0 голосов
/ 23 января 2018

Только для записи, lodash также имеет isObject (значение)

0 голосов
/ 21 ноября 2017

Я знаю, что это было давно, но я решил обновить ответ, поскольку есть новые (более быстрые и простые) способы решения этой проблемы.Поскольку ECMAscript 5.1 йо может использовать метод isArray(), доступный в классе Array.

Йо может видеть его документацию в MDN здесь .

Я думаю, что в настоящее время у вас не должно быть проблем с совместимостью, но на всякий случай, если вы добавите это в свой код, вы всегда должны быть уверены в том, что Array.isArray() является полизаполненным:

if (!Array.isArray) {
  Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };
}
...