JSON-объект, содержащий массив - PullRequest
2 голосов
/ 07 января 2011

У меня есть JSON, например,

var jsondata = {
  "an_array" : [[2,4],[1,2]]
} 

В JavaScript я хочу использовать цикл for для прохождения каждого элемента массива в массиве, например

var grab_array = jsondata.an_array;
for (i = 0; i < grab_array.length; i++) {

 grab_array[i][0]; //doing stuff

}

Тем не менее, и я знаю, что это, вероятно, некоторые серьезные вещи noob, когда я запускаю typeof () на grab_array, он говорит, что это объект и имеет длину 0. Что мне делать?

Ответы [ 4 ]

3 голосов
/ 07 января 2011

Ну, я не могу проследить за партией с length, являющейся 0, вы действительно запустили цикл? Это должно работать просто отлично.

Но в отношении оператора typeof этот оператор (вместе с оператором instanceof), вероятно, является самой большой ошибкой в ​​дизайне JavaScript. Это близко к тому, чтобы быть полностью сломанным .

Хотя instanceof все еще имеет ограниченное использование, typeof действительно имеет только один Практический вариант использования, в котором не происходит проверки типа объекта.

JavaScript Typetable

Value               Class      Type
-------------------------------------
"foo"               String     string
new String("foo")   String     object
1.2                 Number     number
new Number(1.2)     Number     object
true                Boolean    boolean
new Boolean(true)   Boolean    object
new Date()          Date       object
new Error()         Error      object
[1,2,3]             Array      object
new Array(1, 2, 3)  Array      object
new Function("")    Function   function
/abc/g              RegExp     object (function in Nitro/V8)
new RegExp("meow")  RegExp     object (function in Nitro/V8)
{}                  Object     object
new Object()        Object     object

В приведенной выше таблице Тип относится к значению, которое возвращает оператор typeof. Как Вы можете видеть, что это совсем не так.

Класс относится к значению внутреннего свойства [[Class]] объекта.

Из спецификации: Класс может принимать одно из следующих значений: "Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", "String"

Чтобы получить значение Класс , можно использовать toString метод Object.

Проверка класса объекта

function is(type, obj) {
    return Object.prototype.toString.call(obj).slice(8, -1) === type;
}

is('String', 'test'); // true
is('String', new String('test')); // true

В приведенном выше коде Object.prototype.toString вызывается с this устанавливается на объект, который его Класс значение должно быть получено.

Проверка, была ли определена переменная

typeof foo !== 'undefined'

Выше будет проверено, был ли foo фактически объявлен или нет, так как просто ссылка на него приведет к ReferenceError. Это единственное typeof на самом деле полезно для.

Подводя итог

Не используйте typeof, если вы не проверяете наличие переменной.

2 голосов
/ 07 января 2011

Ну, а я могу легко запустить этот код

var jsondata = {
  "an_array" : [[2,4],[1,2]]
}
var grab_array = jsondata.an_array, 
    max = grab_array.length;
for (i = 0; i < max; i++) {

 console.log(grab_array[i][0]); 

}

и результат был довольно ожидаемый: 2, 1 (каждый на новой строке). Что касается второй части вопроса, вы можете легко проверить, является ли grab_array массивом или нет, используя следующий фрагмент:

if (grab_array.constructor == Array){
  //do stuff
}

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

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

, а затем просто сделайте:

if (Array.isArray()){
  //do stuff
}
1 голос
/ 07 января 2011

Просто используйте grab_array.constructor == Array вместо typeof grab_array при проверке типа.

0 голосов
/ 07 января 2011

Я не уверен, что здесь происходит, если честно.Создание кода как есть через JQuery JSON-анализатор приводит меня к результату, где an_array.length равен 2. typeof по-прежнему перечисляет его как объект, но он имеет длину, и ваш цикл должен пройти через него.Возможно, вам пригодится больше кода.

В качестве подсказки отладки попробуйте выполнить вызов console.log в Chrome или Firefox с помощью Firebug из jsondata и посмотреть, что получится.Убедитесь, что объект JSON возвращается правильно.Тем не менее, вы также можете использовать утилиты jQuery для прохождения каждого элемента вместо цикла for.Попробуйте использовать jQuery.each () .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...