Bagaimana cara memeriksa apakah objek JavaScript adalah JSON

91

Saya memiliki objek JSON bersarang yang perlu saya putar ulang, dan nilai setiap kunci bisa berupa String, array JSON, atau objek JSON lainnya. Bergantung pada jenis objek, saya perlu melakukan operasi yang berbeda. Apakah ada cara agar saya dapat memeriksa jenis objek untuk melihat apakah itu adalah String, objek JSON, atau array JSON?

Saya mencoba menggunakan typeofdan instanceoftetapi keduanya tampaknya tidak berhasil, karena typeofakan mengembalikan objek untuk objek dan array JSON, dan instanceofmemberikan kesalahan ketika saya melakukannya obj instanceof JSON.

Untuk lebih spesifik, setelah mem-parsing JSON menjadi objek JS, adakah cara untuk memeriksa apakah itu string normal, atau objek dengan kunci dan nilai (dari objek JSON), atau array (dari array JSON )?

Sebagai contoh:

JSON

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

Contoh JavaScript

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
    }
}

Bagaimana cara saya melakukan pengecekan objek seperti gambar di atas?

Wei Hao
sumber
3
JSON hanyalah notasi yang disimpan sebagai string . Apakah Anda yakin tidak membingungkan istilah?
zerkms
Tidak, saya memperbarui pertanyaan agar lebih jelas. Saya kira pertanyaan utama saya adalah apa yang terjadi setelah kita melakukan .parse()pada string JSON, dan bagaimana mengidentifikasinya?
Wei Hao
1
perubahan belum membuatnya lebih jelas (setidaknya bagi saya). Bagaimana jika Anda memberikan contoh JSON yang Anda hadapi
zerkms
Pertanyaan yang diperbarui dengan sebuah contoh. (:
Wei Hao
Pertanyaan sebenarnya adalah: mengapa Anda peduli?
Asherah

Jawaban:

130

Saya akan memeriksa atribut konstruktor.

misalnya

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

Edit: Menambahkan pemeriksaan nol dan pemeriksaan tidak ditentukan.

Orang Pemrograman
sumber
9
else iftidak diperlukan
McSonk
Bukankah ini sama dengan menggunakan instanceof? developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…
Pereira
@ Pereira: JavaScript memiliki beberapa kerutan yang membingungkan. Coba contoh "sure_this_is_a_string" dari String.
Pemrograman Guy
{}.constructormenyebabkan saya masuk ke ERROR TypeError: Cannot read property 'constructor' of undefinedaplikasi sudut saya.
kebab-case
1
Begitu banyak ifpernyataan ... Gunakan a switch!
Nanoo
26

Anda dapat menggunakan Array.isArray untuk memeriksa array. Kemudian ketikkan obj == 'string' , dan ketik obj == 'objek' .

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' adalah string
'a' adalah array
'o' adalah objek
'i' adalah lainnya

McGarnagle
sumber
5
Jangan lupa untuk memperhitungkannyatypeof null === 'object'
hugomg
[{ "name":[ {"key": "any key" } ] }] ini juga json valid tetapi array yang dikembalikan oleh kode Anda. periksa ini - biola
Sudhir K Gupta
17

Objek JSON adalah objek. Untuk memeriksa apakah suatu tipe adalah tipe objek, evaluasi properti konstruktor.

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

Hal yang sama berlaku untuk semua jenis lainnya:

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;
}
Martin Wantke
sumber
3
Sumber daya yang dikodekan JSON bukan objek. Itu adalah sebuah string. Hanya setelah Anda mendekodekannya atau dalam Javascript JSON.parse(), sumber daya JSON menjadi objek. Oleh karena itu, jika Anda menguji sumber daya yang berasal dari server untuk melihat apakah itu JSON, yang terbaik adalah memeriksa terlebih dahulu untuk String, kemudian jika bukan a <empty string>dan kemudian setelah mem-parsing apakah itu sebuah objek.
Hmerman6006
8

Jika Anda mencoba untuk memeriksa jenis objectsetelah Anda mengurai JSONstring, saya sarankan untuk memeriksa atribut konstruktor:

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

Ini akan menjadi pemeriksaan yang jauh lebih cepat daripada jenis atau contoh.

Jika perpustakaan JSON tidak mengembalikan objek yang dibangun dengan fungsi-fungsi ini, saya akan sangat mencurigainya.

JoshRagem
sumber
Pendekatan yang jauh lebih langsung. Terima kasih! = D
Eduardo Lucio
Jawaban yang disukai. Dari mana Anda mendapatkan info manfaat kinerja?
Daniel F
@DanielF itu adalah kebijaksanaan umum di '12, semuanya berbeda sekarang jadi saya tidak tahu apakah itu berlaku
JoshRagem
5

Anda dapat membuat konstruktor Anda sendiri untuk penguraian JSON:

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

Kemudian periksa instanceof untuk melihat apakah awalnya perlu diurai

test instanceof JSONObj
matt3141
sumber
5

Jawaban oleh @PeterWilkinson tidak berfungsi untuk saya karena konstruktor untuk objek yang "diketik" disesuaikan dengan nama objek tersebut. Saya harus bekerja dengan typeof

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

Saya menulis modul npm untuk mengatasi masalah ini. Ini tersedia di sini :

object-types: modul untuk menemukan jenis literal apa yang mendasari objek

Install

  npm install --save object-types


Pemakaian

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

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

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

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

Lihatlah, itu seharusnya menyelesaikan masalah Anda yang sebenarnya. Beri tahu saya jika Anda memiliki pertanyaan! https://github.com/dawsonbotsford/object-types

Dawson B
sumber
2

Anda juga dapat mencoba mengurai data dan kemudian memeriksa apakah Anda mendapat objek:

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

Saya menggabungkan operator typeof dengan pemeriksaan atribut konstruktor (oleh 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'));
});

Hasil:

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

Mengapa tidak memeriksa Nomor - sedikit lebih pendek dan berfungsi di 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]));
}

Tom
sumber
2

Saya tahu ini adalah pertanyaan yang sangat lama dengan jawaban yang bagus. Namun, tampaknya masih mungkin untuk menambahkan 2 ¢ saya padanya.

Dengan asumsi bahwa Anda mencoba menguji bukan objek JSON itu sendiri tetapi String yang diformat sebagai JSON (yang tampaknya menjadi kasus Anda var data), Anda dapat menggunakan fungsi berikut yang mengembalikan boolean (adalah atau bukan ' 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
  }

}

Berikut beberapa contoh penggunaan fungsi di atas:

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

Saat Anda menjalankan kode di atas, Anda akan mendapatkan hasil sebagai berikut:

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

Silakan, coba cuplikan di bawah dan beri tahu kami jika ini berhasil untuk Anda. :)

PENTING: fungsi yang disajikan dalam posting ini diadaptasi dari https://airbrake.io/blog/javascript-error-handling/syntaxerror-json-parse-bad-parsing di mana Anda dapat menemukan detail yang lebih banyak dan menarik tentang JSON.parse ( ) fungsi.

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

Almir Campos
sumber
1

Coba ini

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

Ini berfungsi untuk contoh di bawah ini

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 ) );
Sandro Rosa
sumber
0

Jawaban Peter dengan cek tambahan! Tentu saja, tidak dijamin 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!");
}
Eduardo Lucio
sumber
0

Berdasarkan jawaban @Martin Wantke, tetapi dengan beberapa perbaikan / penyesuaian yang disarankan ...

// NOTE: Check JavaScript type. By Questor
function getJSType(valToChk) {

    function isUndefined(valToChk) { return valToChk === undefined; }
    function isNull(valToChk) { return valToChk === null; }
    function isArray(valToChk) { return valToChk.constructor == Array; }
    function isBoolean(valToChk) { return valToChk.constructor == Boolean; }
    function isFunction(valToChk) { return valToChk.constructor == Function; }
    function isNumber(valToChk) { return valToChk.constructor == Number; }
    function isString(valToChk) { return valToChk.constructor == String; }
    function isObject(valToChk) { return valToChk.constructor == Object; }

    if(isUndefined(valToChk)) { return "undefined"; }
    if(isNull(valToChk)) { return "null"; }
    if(isArray(valToChk)) { return "array"; }
    if(isBoolean(valToChk)) { return "boolean"; }
    if(isFunction(valToChk)) { return "function"; }
    if(isNumber(valToChk)) { return "number"; }
    if(isString(valToChk)) { return "string"; }
    if(isObject(valToChk)) { return "object"; }

}

CATATAN: Saya menemukan pendekatan ini sangat didaktik, jadi saya mengirimkan jawaban ini.

Eduardo Lucio
sumber
-5

coba cara kotor ini

 ('' + obj).includes('{')
Stan Sokolov
sumber