Cách kiểm tra xem đối tượng JavaScript có phải là JSON không


87

Tôi có một đối tượng JSON lồng nhau mà tôi cần lặp qua và giá trị của mỗi khóa có thể là một Chuỗi, mảng JSON hoặc một đối tượng JSON khác. Tùy từng loại đối tượng mà tôi cần thực hiện các thao tác khác nhau. Có cách nào tôi có thể kiểm tra loại đối tượng để xem nó là chuỗi, đối tượng JSON hay mảng JSON?

Tôi đã thử sử dụng typeofinstanceofnhưng cả hai dường như không hoạt động, vì typeofsẽ trả về một đối tượng cho cả đối tượng và mảng JSON và instanceofđưa ra lỗi khi tôi thực hiện obj instanceof JSON.

Cụ thể hơn, sau khi phân tích cú pháp JSON thành một đối tượng JS, có cách nào tôi có thể kiểm tra xem nó là một chuỗi bình thường hay một đối tượng có khóa và giá trị (từ một đối tượng JSON) hay một mảng (từ một mảng JSON )?

Ví dụ:

JSON

var data = "{'hi':
             {'hello':
               ['hi1','hi2']
             },
            'hey':'words'
           }";

JavaScript mẫu

var jsonObj = JSON.parse(data);
var path = ["hi","hello"];

function check(jsonObj, path) {
    var parent = jsonObj;
    for (var i = 0; i < path.length-1; i++) {
        var key = path[i];
        if (parent != undefined) {
            parent = parent[key];
        }
    }
    if (parent != undefined) {
        var endLength = path.length - 1;
        var child = parent[path[endLength]];
        //if child is a string, add some text
        //if child is an object, edit the key/value
        //if child is an array, add a new element
        //if child does not exist, add a new key/value
    }
}

Làm cách nào để thực hiện kiểm tra đối tượng như hình trên?


3
JSON chỉ là một ký hiệu được lưu trữ dưới dạng một chuỗi . Bạn có chắc mình không nhầm lẫn các thuật ngữ?
zerkms

Không, tôi đã cập nhật câu hỏi để làm rõ hơn. Tôi đoán câu hỏi chính của tôi là điều gì sẽ xảy ra sau khi chúng tôi thực hiện một .parse()chuỗi JSON và làm thế nào để xác định nó?
Wei Hao

1
sự thay đổi đã không làm cho nó rõ ràng hơn (với tôi). Điều gì nếu bạn cung cấp cho ví dụ về JSON bạn đối phó với
zerkms

Cập nhật câu hỏi với một ví dụ. (:
Wei Hao

Câu hỏi thực sự là: tại sao bạn quan tâm?
Asherah

Câu trả lời:


130

Tôi sẽ kiểm tra thuộc tính hàm tạo.

ví dụ

var stringConstructor = "test".constructor;
var arrayConstructor = [].constructor;
var objectConstructor = ({}).constructor;

function whatIsIt(object) {
    if (object === null) {
        return "null";
    }
    if (object === undefined) {
        return "undefined";
    }
    if (object.constructor === stringConstructor) {
        return "String";
    }
    if (object.constructor === arrayConstructor) {
        return "Array";
    }
    if (object.constructor === objectConstructor) {
        return "Object";
    }
    {
        return "don't know";
    }
}

var testSubjects = ["string", [1,2,3], {foo: "bar"}, 4];

for (var i=0, len = testSubjects.length; i < len; i++) {
    alert(whatIsIt(testSubjects[i]));
}

Chỉnh sửa: Đã thêm một séc rỗng và một séc không xác định.


9
else iflà không cần thiết
McSonk

Điều này không giống như sử dụng instanceof? developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…
Pereira

@Pereira: JavaScript có một số nếp nhăn khó hiểu. Hãy thử "sure_this_is_a_string" instanceof String.
Lập trình Guy

{}.constructorđang khiến tôi ERROR TypeError: Cannot read property 'constructor' of undefinedvướng vào ứng dụng góc cạnh của mình.
okay_programmer

@ Minyc510: Có vẻ như hành vi của trình duyệt đã thay đổi. Gói gọn trong ngoặc có vẻ khắc phục được điều đó. Tôi đã chỉnh sửa câu trả lời để phản ánh điều này.
Lập trình Guy

25

Bạn có thể sử dụng Array.isArray để kiểm tra các mảng. Sau đó, typeof obj == 'string' , và typeof obj == 'object' .

var s = 'a string', a = [], o = {}, i = 5;
function getType(p) {
    if (Array.isArray(p)) return 'array';
    else if (typeof p == 'string') return 'string';
    else if (p != null && typeof p == 'object') return 'object';
    else return 'other';
}
console.log("'s' is " + getType(s));
console.log("'a' is " + getType(a));
console.log("'o' is " + getType(o));
console.log("'i' is " + getType(i));

's' là chuỗi
'a' là mảng
'o' là đối tượng
'i' là khác


5
Đừng quên tính đến điều đótypeof null === 'object'
ôm vào

[{ "name":[ {"key": "any key" } ] }] đây cũng là json hợp lệ nhưng trả về mảng của nó bởi mã của bạn. kiểm tra điều này - fiddle
Sudhir K Gupta

15

Đối tượng JSON một đối tượng. Để kiểm tra xem một kiểu có phải là một kiểu đối tượng hay không, hãy đánh giá thuộc tính phương thức khởi tạo.

function isObject(obj)
{
    return obj !== undefined && obj !== null && obj.constructor == Object;
}

Điều tương tự cũng áp dụng cho tất cả các loại khác:

function isArray(obj)
{
    return obj !== undefined && obj !== null && obj.constructor == Array;
}

function isBoolean(obj)
{
    return obj !== undefined && obj !== null && obj.constructor == Boolean;
}

function isFunction(obj)
{
    return obj !== undefined && obj !== null && obj.constructor == Function;
}

function isNumber(obj)
{
    return obj !== undefined && obj !== null && obj.constructor == Number;
}

function isString(obj)
{
    return obj !== undefined && obj !== null && obj.constructor == String;
}

function isInstanced(obj)
{
    if(obj === undefined || obj === null) { return false; }

    if(isArray(obj)) { return false; }
    if(isBoolean(obj)) { return false; }
    if(isFunction(obj)) { return false; }
    if(isNumber(obj)) { return false; }
    if(isObject(obj)) { return false; }
    if(isString(obj)) { return false; }

    return true;
}

2
Tài nguyên được mã hóa JSON không phải là một đối tượng. Nó là một chuỗi. Chỉ sau khi bạn giải mã nó hoặc trong Javascript JSON.parse()thì tài nguyên JSON mới trở thành một đối tượng. Do đó, nếu bạn kiểm tra một tài nguyên đến từ một máy chủ để xem nó có phải là JSON hay không, tốt nhất là trước tiên hãy kiểm tra String, sau đó nếu không phải là a <empty string>và sau đó phân tích cú pháp xem nó có phải là một đối tượng hay không.
Hmerman6006

8

Nếu bạn đang cố gắng kiểm tra kiểu của một objectsau khi bạn phân tích cú pháp một JSONchuỗi, tôi khuyên bạn nên kiểm tra thuộc tính hàm tạo:

obj.constructor == Array || obj.constructor == String || obj.constructor == Object

Đây sẽ là cách kiểm tra nhanh hơn nhiều so với typeof hoặc instanceof.

Nếu một thư viện JSON không trả về các đối tượng được xây dựng bằng các hàm này, tôi sẽ rất nghi ngờ khi sử dụng nó.


Một cách tiếp cận trực tiếp hơn nhiều. Cảm ơn! = D
Eduardo Lucio

Câu trả lời ưu tiên. Bạn lấy thông tin lợi ích về hiệu suất từ ​​đâu?
Daniel F

@DanielF nó là sự khôn ngoan thông thường trở lại vào năm '12, mọi thứ giờ đã khác nên tôi không biết liệu điều đó có đúng không
JoshRagem

5

Câu trả lời của @PeterWilkinson không phù hợp với tôi bởi vì một phương thức khởi tạo cho một đối tượng "đã nhập" được tùy chỉnh theo tên của đối tượng đó. Tôi đã phải làm việc với typeof

function isJson(obj) {
    var t = typeof obj;
    return ['boolean', 'number', 'string', 'symbol', 'function'].indexOf(t) == -1;
}

4

Bạn có thể tạo phương thức khởi tạo của riêng mình để phân tích cú pháp JSON:

var JSONObj = function(obj) { $.extend(this, JSON.parse(obj)); }
var test = new JSONObj('{"a": "apple"}');
//{a: "apple"}

Sau đó, kiểm tra instanceof để xem liệu nó có cần phân tích cú pháp ban đầu hay không

test instanceof JSONObj

4

Tôi đã viết một mô-đun npm để giải quyết vấn đề này. Nó có sẵn ở đây :

object-types: một mô-đun để tìm các loại đối tượng cơ bản theo nghĩa đen

Tải về

  npm install --save object-types


Sử dụng

const objectTypes = require('object-types');

objectTypes({});
//=> 'object'

objectTypes([]);
//=> 'array'

objectTypes(new Object(true));
//=> 'boolean'

Hãy xem, nó sẽ giải quyết vấn đề chính xác của bạn. Hãy cho tôi biết nếu bạn có bất kỳ câu hỏi! https://github.com/dawsonbotsford/object-types


2

bạn cũng có thể thử phân tích cú pháp dữ liệu và sau đó kiểm tra xem bạn có đối tượng không:

var testIfJson = JSON.parse(data);
if (typeOf testIfJson == "object")
{
//Json
}
else
{
//Not Json
}

2

Tôi kết hợp toán tử typeof với kiểm tra thuộc tính hàm tạo (bởi Peter):

var typeOf = function(object) {
    var firstShot = typeof object;
    if (firstShot !== 'object') {
        return firstShot;
    } 
    else if (object.constructor === [].constructor) {
        return 'array';
    }
    else if (object.constructor === {}.constructor) {
        return 'object';
    }
    else if (object === null) {
        return 'null';
    }
    else {
        return 'don\'t know';
    } 
}

// Test
var testSubjects = [true, false, 1, 2.3, 'string', [4,5,6], {foo: 'bar'}, null, undefined];

console.log(['typeOf()', 'input parameter'].join('\t'))
console.log(new Array(28).join('-'));
testSubjects.map(function(testSubject){
    console.log([typeOf(testSubject), JSON.stringify(testSubject)].join('\t\t'));
});

Kết quả:

typeOf()    input parameter
---------------------------
boolean     true
boolean     false
number      1
number      2.3
string      "string"
array       [4,5,6]
object      {"foo":"bar"}
null        null
undefined       

2

Tôi biết đây là một câu hỏi rất cũ với những câu trả lời hay. Tuy nhiên, có vẻ như vẫn có thể thêm 2 ¢ của tôi vào đó.

Giả sử rằng bạn đang cố gắng kiểm tra không phải bản thân đối tượng JSON mà là một Chuỗi được định dạng là JSON (có vẻ như trường hợp của bạn var data), bạn có thể sử dụng hàm sau để trả về một boolean (có hoặc không phải là ' JSON '):

function isJsonString( jsonString ) {

  // This function below ('printError') can be used to print details about the error, if any.
  // Please, refer to the original article (see the end of this post)
  // for more details. I suppressed details to keep the code clean.
  //
  let printError = function(error, explicit) {
  console.log(`[${explicit ? 'EXPLICIT' : 'INEXPLICIT'}] ${error.name}: ${error.message}`);
  }


  try {
      JSON.parse( jsonString );
      return true; // It's a valid JSON format
  } catch (e) {
      return false; // It's not a valid JSON format
  }

}

Dưới đây là một số ví dụ về việc sử dụng hàm trên:

console.log('\n1 -----------------');
let j = "abc";
console.log( j, isJsonString(j) );

console.log('\n2 -----------------');
j = `{"abc": "def"}`;
console.log( j, isJsonString(j) );

console.log('\n3 -----------------');
j = '{"abc": "def}';
console.log( j, isJsonString(j) );

console.log('\n4 -----------------');
j = '{}';
console.log( j, isJsonString(j) );

console.log('\n5 -----------------');
j = '[{}]';
console.log( j, isJsonString(j) );

console.log('\n6 -----------------');
j = '[{},]';
console.log( j, isJsonString(j) );

console.log('\n7 -----------------');
j = '[{"a":1, "b":   2}, {"c":3}]';
console.log( j, isJsonString(j) );

Khi bạn chạy đoạn mã trên, bạn sẽ nhận được kết quả sau:

1 -----------------
abc false

2 -----------------
{"abc": "def"} true

3 -----------------
{"abc": "def} false

4 -----------------
{} true

5 -----------------
[{}] true

6 -----------------
[{},] false

7 -----------------
[{"a":1, "b":   2}, {"c":3}] true

Vui lòng thử đoạn mã dưới đây và cho chúng tôi biết nếu điều này có hiệu quả với bạn. :)

QUAN TRỌNG: chức năng được trình bày trong bài đăng này được điều chỉnh từ https://airbrake.io/blog/javascript-error-handling/syntaxerror-json-parse-bad-parsing , nơi bạn có thể tìm thấy nhiều chi tiết thú vị hơn về JSON.parse ( ) chức năng.

function isJsonString( jsonString ) {

  let printError = function(error, explicit) {
  console.log(`[${explicit ? 'EXPLICIT' : 'INEXPLICIT'}] ${error.name}: ${error.message}`);
  }


  try {
      JSON.parse( jsonString );
      return true; // It's a valid JSON format
  } catch (e) {
      return false; // It's not a valid JSON format
  }

}


console.log('\n1 -----------------');
let j = "abc";
console.log( j, isJsonString(j) );

console.log('\n2 -----------------');
j = `{"abc": "def"}`;
console.log( j, isJsonString(j) );

console.log('\n3 -----------------');
j = '{"abc": "def}';
console.log( j, isJsonString(j) );

console.log('\n4 -----------------');
j = '{}';
console.log( j, isJsonString(j) );

console.log('\n5 -----------------');
j = '[{}]';
console.log( j, isJsonString(j) );

console.log('\n6 -----------------');
j = '[{},]';
console.log( j, isJsonString(j) );

console.log('\n7 -----------------');
j = '[{"a":1, "b":   2}, {"c":3}]';
console.log( j, isJsonString(j) );


1

Thử đi

if ( typeof is_json != "function" )
function is_json( _obj )
{
    var _has_keys = 0 ;
    for( var _pr in _obj )
    {
        if ( _obj.hasOwnProperty( _pr ) && !( /^\d+$/.test( _pr ) ) )
        {
           _has_keys = 1 ;
           break ;
        }
    }

    return ( _has_keys && _obj.constructor == Object && _obj.constructor != Array ) ? 1 : 0 ;
}

Nó hoạt động cho ví dụ bên dưới

var _a = { "name" : "me",
       "surname" : "I",
       "nickname" : {
                      "first" : "wow",
                      "second" : "super",
                      "morelevel" : {
                                      "3level1" : 1,
                                      "3level2" : 2,
                                      "3level3" : 3
                                    }
                    }
     } ;

var _b = [ "name", "surname", "nickname" ] ;
var _c = "abcdefg" ;

console.log( is_json( _a ) );
console.log( is_json( _b ) );
console.log( is_json( _c ) );

1

Tại sao không kiểm tra Số - ngắn hơn một chút và hoạt động trong IE / Chrome / FF / node.js

function whatIsIt(object) {
    if (object === null) {
        return "null";
    }
    else if (object === undefined) {
        return "undefined";
    }
    if (object.constructor.name) {
            return object.constructor.name;
    }
    else { // last chance 4 IE: "\nfunction Number() {\n    [native code]\n}\n" / node.js: "function String() { [native code] }"
        var name = object.constructor.toString().split(' ');
        if (name && name.length > 1) {
            name = name[1];
            return name.substr(0, name.indexOf('('));
        }
        else { // unreachable now(?)
            return "don't know";
        }
    }
}

var testSubjects = ["string", [1,2,3], {foo: "bar"}, 4];
// Test all options
console.log(whatIsIt(null));
console.log(whatIsIt());
for (var i=0, len = testSubjects.length; i < len; i++) {
    console.log(whatIsIt(testSubjects[i]));
}


0

Câu trả lời của Peter với một kiểm tra bổ sung! Tất nhiên, không đảm bảo 100%!

var isJson = false;
outPutValue = ""
var objectConstructor = {}.constructor;
if(jsonToCheck.constructor === objectConstructor){
    outPutValue = JSON.stringify(jsonToCheck);
    try{
            JSON.parse(outPutValue);
            isJson = true;
    }catch(err){
            isJson = false;
    }
}

if(isJson){
    alert("Is json |" + JSON.stringify(jsonToCheck) + "|");
}else{
    alert("Is other!");
}

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.