Trong javascript làm thế nào chúng ta có thể xác định xem một đối tượng là Hash hay Array?


77

Đầu ra của lệnh gọi JSON của tôi có thể là Mảng hoặc Hash. Làm thế nào để tôi phân biệt giữa hai điều này?

Câu trả lời:


125

Các trình duyệt hiện đại hỗ trợ Array.isArray(obj)phương pháp này.

Xem MDN để biết tài liệu và một polyfill.

= câu trả lời ban đầu từ năm 2008 =

bạn có thể sử dụng thuộc tính hằng số của đầu ra của mình:

if(output.constructor == Array){
}
else if(output.constructor == Object){
}

2
Điều này có khả năng xảy ra xung đột giữa các trang khác nhau, vì cả hai đều có các phiên bản khác nhau của hàm ArrayObjecthàm tạo, sẽ không so sánh bằng nhau. Tôi không chắc làm thế nào để tạo ra một ví dụ chứng minh điều này, nhưng tôi đã đọc nó ở đâu đó.
ripper234,

1
@ ripper234 Vấn đề sẽ tự biểu hiện trong windowmôi trường đa .
alex

3
+1 cho metioning Array.isArray. Kiểm tra liên kết này để được hỗ trợ borwser
SKuijers

1
Bất kỳ ai sử dụng underscore.js đều có thể thấy isArrayisObject hữu ích.
akotian

1
@akotian _.isObject trả về true cho cả mảng và băm, thật không may. Bạn sẽ cần thêm logic có điều kiện để đưa ra giải pháp có dấu gạch dưới.
Con Antonakos

31

Là đối tượng:

function isObject ( obj ) {
   return obj && (typeof obj  === "object");
}

Là mảng:

function isArray ( obj ) { 
  return isObject(obj) && (obj instanceof Array);
}

Vì mảng là đối tượng nên trước tiên bạn sẽ muốn kiểm tra xem một biến có phải là mảng hay không và sau đó nếu nó là một đối tượng:

if (isArray(myObject)) {
   // do stuff for arrays
}
else if (isObject(myObject)) {
   // do stuff for objects
}

1
Câu trả lời tốt. Bạn có thể muốn thêm mọi đối tượng js có thể được coi như một hàm băm.
Rontologist 20/10/08

isObject (new Date ())) là true, nhưng ngày không phải là một đối tượng / hash theo nghĩa của câu hỏi này. Tất nhiên chúng tôi chỉ áp dụng nó cho JSON, nhưng tên phương thức thực sự khó hiểu khi đó.
schirrmacher

isObjectlợi nhuận đúng đối với cả hai đối tượng và mảng như vậy là không cần thiết
hacklikecrack

9

Ý của bạn là "Đối tượng" thay vì "Băm"?

>>> var a = [];
>>> var o = {};
>>> a instanceof Array
true
>>> o instanceof Array
false

5

Tôi đã tạo một hàm để xác định xem đó có phải là một từ điển hay không.

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);

Cám ơn vì cái này. Nó đã hoạt động cho các trường hợp nêu trên. Tôi vẫn chưa gặp phải trường hợp mà phương pháp của bạn không thành công.
Nav

1
if(Array.isArray(obj)) return false;<- Điều này không thừa vì một mảng sẽ không vượt qua lần kiểm tra tiếp theo ( if(obj.constructor != Object))?

assert.equal(is_dictionary(new (class MyClass {})), true);không thành công - trường hợp của MyClass được định nghĩa là một băm / từ điển.
Angelos Pikoulas

Cải thiện nó một chút: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
Angelos Pikoulas

1

Kiểm tra thuộc tính "constructor" trên đối tượng. Nó là Mảng - nó là một đối tượng mảng.

var a = {
 'b': {length: 0},
 'c': [1,2]
}

if (acconstructor == Array)
   for (var i = 0; i <aclength; i ++)
      alert (ac [i]);
khác
   for (var s in ab);
      alert (ab [s]);


0

Để phân tích cú pháp json có thể hữu ích :)

isArrayHashs = (attr) ->
  !!attr && attr.constructor == Array && isHash(attr[0])

isHash = (attr) ->
  !!attr && !$.isNumeric(attr) && attr.constructor == Object

attr [0] .constructor phải là:

  • Chuỗi
  • Số
  • Mảng
  • Vật
  • Chưa xác định

0

Một thuật ngữ thực tế và chính xác hơn đối tượng hoặc băm hoặc từ điển có thể là mảng kết hợp . Đối tượng có thể áp dụng cho nhiều không yêu cầu, ví dụ: typeof null === 'object'hoặc [1,2,3] instanceof Object. Hai chức năng sau hoạt động kể từ ES3 và tự nhiên là độc quyền.

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 () {}));

Lưu ý cách điều này sẽ coi thể hiện của một lớp như một mảng kết hợp. (Nhưng không phải trường hợp của một lớp dựng sẵn, chẳng hạn như Ngày.)

Cảm ơn giải pháp của RobG dọc theo những dòng này cho một polyfill Array.isArray (). Thao tác này nhấn vào phương thức toString () gốc của lớp Object, phương thức này sẽ loại báo cáo ngắn gọn và hiệu quả.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.