Результатом мого виклику JSON може бути масив або хеш. Як розрізнити ці два?
Відповіді:
Сучасні браузери підтримують Array.isArray(obj)метод.
Документацію та поліфіл див. У MDN .
= оригінальна відповідь від 2008 =
Ви можете використовувати властивість constuctor вашого виводу:
if(output.constructor == Array){
}
else if(output.constructor == Object){
}
windowсередовищі.
Є об’єктом:
function isObject ( obj ) {
return obj && (typeof obj === "object");
}
Є масив:
function isArray ( obj ) {
return isObject(obj) && (obj instanceof Array);
}
Оскільки масиви - це об’єкти, які ви хочете перевірити, чи є змінна спочатку масивом, а потім, якщо це об’єкт:
if (isArray(myObject)) {
// do stuff for arrays
}
else if (isObject(myObject)) {
// do stuff for objects
}
isObjectповертає істину як для об'єктів, так і для масивів, тому є надлишковим
Ви мали на увазі "Об'єкт" замість "Хеш"?
>>> var a = [];
>>> var o = {};
>>> a instanceof Array
true
>>> o instanceof Array
false
Я створив функцію для визначення, чи це словник.
exports.is_dictionary = function (obj) {
if(!obj) return false;
if(Array.isArray(obj)) return false;
if(obj.constructor != Object) return false;
return true;
};
// return true
test.equal(nsa_utils.is_dictionary({}), true);
test.equal(nsa_utils.is_dictionary({abc:123, def:456}), true);
// returns false
test.equal(nsa_utils.is_dictionary([]), false);
test.equal(nsa_utils.is_dictionary([123, 456]), false);
test.equal(nsa_utils.is_dictionary(null), false);
test.equal(nsa_utils.is_dictionary(NaN), false);
test.equal(nsa_utils.is_dictionary('hello'), false);
test.equal(nsa_utils.is_dictionary(0), false);
test.equal(nsa_utils.is_dictionary(123), false);
if(Array.isArray(obj)) return false;<- Хіба це не зайве, враховуючи, що масив все одно не пройде наступну перевірку ( if(obj.constructor != Object))?
assert.equal(is_dictionary(new (class MyClass {})), true);не вдається - екземпляр MyClass, безумовно, є хешем / словником.
const assert = require('assert'); const is_dictionary = function (obj) { if(!obj) return false; if(Array.isArray(obj)) return false; if (({}).toString.apply(obj) !== '[object Object]') return false; return true; }; // returns true along your own with these values new (class MyClass {}) Object.create({}) Object.create(null) // returns false along with yours new String('foo') new Number(123) ()=> {} function() {} new Map
Перевірте властивість "конструктор" на об'єкті. Це Array - це об’єкт масиву.
var a = {
'b': {довжина: 0},
'c': [1,2]
}
якщо (acconstructor == масив)
для (var i = 0; i <aclength; i ++)
попередження (ac [i]);
ще
для (var s in ab);
попередження (ab [s]);
Для розбору json може стати в нагоді :)
isArrayHashs = (attr) ->
!!attr && attr.constructor == Array && isHash(attr[0])
isHash = (attr) ->
!!attr && !$.isNumeric(attr) && attr.constructor == Object
attr [0] .constructor повинен бути:
Більш практичний і точний термін, ніж об’єкт, хеш чи словник, може бути асоціативним масивом . Об'єкт може застосовуватися до багатьох небажаних випадків, наприклад typeof null === 'object'або [1,2,3] instanceof Object. Наступні дві функції працюють з ES3 і є природно ексклюзивними.
function is_array(z) {
return Object.prototype.toString.call(z) === '[object Array]';
}
console.assert(true === is_array([]));
console.assert(true === is_array([1,2,3]));
console.assert(true === is_array(new Array));
console.assert(true === is_array(Array(1,2,3)));
console.assert(false === is_array({a:1, b:2}));
console.assert(false === is_array(42));
console.assert(false === is_array("etc"));
console.assert(false === is_array(null));
console.assert(false === is_array(undefined));
console.assert(false === is_array(true));
console.assert(false === is_array(function () {}));
function is_associative_array(z) {
return Object.prototype.toString.call(z) === '[object Object]';
}
console.assert(true === is_associative_array({a:1, b:2}));
console.assert(true === is_associative_array(new function Legacy_Class(){}));
console.assert(true === is_associative_array(new class ES2015_Class{}));
console.assert(false === is_associative_array(window));
console.assert(false === is_associative_array(new Date()));
console.assert(false === is_associative_array([]));
console.assert(false === is_associative_array([1,2,3]));
console.assert(false === is_associative_array(Array(1,2,3)));
console.assert(false === is_associative_array(42));
console.assert(false === is_associative_array("etc"));
console.assert(false === is_associative_array(null));
console.assert(false === is_associative_array(undefined));
console.assert(false === is_associative_array(true));
console.assert(false === is_associative_array(function () {}));
Зверніть увагу, як це буде розглядати екземпляр класу як асоціативний масив. (Але не екземпляр вбудованого класу, такого як Date.)
Завдяки рішенню RobG у цьому напрямку для поліфіру Array.isArray (). Це торкається власного методу toString () класу Object, який стисло і ефективно повідомляє про тип.
ArrayіObjectконструктора, які не можуть порівнюватися як рівні. Я не зовсім впевнений, як навести приклад, який це демонструє, але я десь його читав.