JavaScript nesnesinin JSON olup olmadığı nasıl kontrol edilir


91

Döngüye girmem gereken iç içe geçmiş bir JSON nesnem var ve her anahtarın değeri bir String, JSON dizisi veya başka bir JSON nesnesi olabilir. Nesnenin türüne bağlı olarak farklı işlemler yapmam gerekiyor. Bir String, JSON nesnesi veya JSON dizisi olup olmadığını görmek için nesnenin türünü kontrol etmemin bir yolu var mı?

Hem JSON nesnesi hem de dizi için bir nesne döndürecek ve yaptığımda hata veriyor gibi typeofve kullanmayı denedim instanceofama ikisi de işe yaramadı .typeofinstanceofobj instanceof JSON

Daha spesifik olmak gerekirse, JSON'u bir JS nesnesine ayrıştırdıktan sonra, bunun normal bir dize olup olmadığını veya anahtarlar ve değerlere sahip bir nesne (JSON nesnesinden) veya bir dizi (JSON dizisinden) olup olmadığını kontrol etmenin herhangi bir yolu var mı? )?

Örneğin:

JSON

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

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

Yukarıda gösterildiği gibi nesne kontrolünü nasıl yapabilirim?


3
JSON , dizge olarak saklanan bir gösterimdir . Kafanızı karıştırmadığınızdan emin misiniz?
zerkms

Hayır, soruyu daha net hale getirmek için güncelledim. Sanırım asıl sorum, .parse()bir JSON dizesi üzerinde bir yapmamızdan sonra ne olacağı ve onu nasıl tanımlayacağım.
Wei Hao

1
değişiklik daha net hale getirmedi (benim için en az). Ya uğraştığınız JSON örneğini verirseniz
zerkms

Bir örnekle güncellenmiş soru. (:
Wei Hao

Gerçek soru şudur: neden umursuyorsun?
Asherah

Yanıtlar:


130

Yapıcı özelliğini kontrol ederdim.

Örneğin

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

Düzenleme: Bir boş kontrol ve tanımlanmamış bir kontrol eklendi.


9
else ifgereksiz
McSonk

Bu, instanceof'u kullanmakla aynı değil mi? developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…
Pereira

@Pereira: JavaScript'te kafa karıştırıcı bazı kırışıklıklar var. String'in "surely_this_is_a_string" örneğini deneyin.
Programming Guy

{}.constructorERROR TypeError: Cannot read property 'constructor' of undefinedaçısal uygulamama girmeme neden oluyor .
kebab-case

1
Çok fazla ififade ... Kullanın a switch!
Nanoo

26

Dizileri kontrol etmek için Array.isArray'ı kullanabilirsiniz . Sonra typeof obj == 'string' ve 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' dizesi
'a' dizisi
'o' nesnesi
'i' diğeridir


5
Bunu hesaba typeof null === 'object'
katmayı

[{ "name":[ {"key": "any key" } ] }] bu da geçerli bir json ancak kodunuza göre dönüş dizisi. bunu kontrol et - keman
Sudhir K Gupta

17

Bir JSON nesnesi olan bir nesne. Bir türün nesne türü olup olmadığını kontrol etmek için yapıcı özelliğini değerlendirin.

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

Aynısı diğer tüm tipler için de geçerlidir:

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

3
JSON kodlu kaynak bir nesne değil. Bu bir dizedir. Yalnızca siz onu çözdükten sonra veya JavaScript'te JSON.parse()JSON kaynağı bir nesne haline gelir. Bu nedenle, bir sunucudan gelen bir kaynağı JSON olup olmadığını görmek için test ederseniz, en iyisi önce String için, sonra a not a <empty string>olup olmadığını ve sonra bir nesne olup olmadığını ayrıştırmaktır.
Hmerman6006

8

objectBir JSONdizeyi çözümledikten sonra bir türünün türünü kontrol etmeye çalışıyorsanız , yapıcı özelliğini kontrol etmenizi öneririm:

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

Bu, typeof veya instanceof'tan çok daha hızlı bir kontrol olacaktır.

Bir JSON kitaplığı bu işlevlerle oluşturulmuş nesneleri döndürmezse, bundan çok şüpheleniyorum.


Çok daha doğrudan bir yaklaşım. Teşekkürler! = D
Eduardo Lucio

Tercih edilen cevap. Performans avantajı bilgilerini nereden alıyorsunuz?
Daniel F

@DanielF '12'de yaygın bir bilgelikti, şimdi her şey farklı, bu yüzden bunun geçerli olup olmadığını bilmiyorum
JoshRagem

5

JSON ayrıştırması için kendi kurucunuzu yapabilirsiniz:

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

Ardından, orijinal olarak ayrıştırılması gerekip gerekmediğini görmek için instanceof'u kontrol edin

test instanceof JSONObj

5

@PeterWilkinson'ın cevabı benim için işe yaramadı çünkü "yazılmış" bir nesnenin kurucusu, o nesnenin adına göre özelleştirildi. Typeof ile çalışmak zorunda kaldım

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

4

Bu sorunu çözmek için bir npm modülü yazdım. Kullanılabilir burada :

object-types: nesnelerin altında hangi değişmez türleri bulmak için bir modül

Yüklemek

  npm install --save object-types


Kullanım

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

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

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

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

Bir göz atın, probleminizi tam olarak çözmelidir. Herhangi bir sorunuz olursa bana bildirin! https://github.com/dawsonbotsford/object-types


2

Ayrıca verileri ayrıştırmayı deneyebilir ve ardından nesnenin olup olmadığını kontrol edebilirsiniz:

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

2

Typeof operatörünü yapıcı özniteliğinin kontrolüyle birleştiriyorum (Peter tarafından):

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

Sonuç:

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

Neden Numarayı kontrol etmiyorsunuz - biraz daha kısa ve IE / Chrome / FF / node.js'de çalışıyor

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


2

Bunun iyi cevapları olan çok eski bir soru olduğunu biliyorum. Ancak, 2 ¢ eklemek hala mümkün gibi görünüyor.

Bir JSON nesnesinin kendisini değil, JSON olarak biçimlendirilmiş (sizin durumunuzda olduğu gibi) bir String'i test etmeye çalıştığınızı varsayarsak, var databir boole döndüren (bir 'veya değil') aşağıdaki işlevi kullanabilirsiniz. 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
  }

}

İşte yukarıdaki işlevi kullanmanın bazı örnekleri:

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

Yukarıdaki kodu çalıştırdığınızda, aşağıdaki sonuçları alacaksınız:

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

Lütfen aşağıdaki pasajı deneyin ve bunun sizin için uygun olup olmadığını bize bildirin. :)

ÖNEMLİ: Bu yazıda sunulan işlev , JSON.parse hakkında daha fazla ve ilginç ayrıntı bulabileceğiniz https://airbrake.io/blog/javascript-error-handling/syntaxerror-json-parse-bad-parsing'den uyarlanmıştır ) işlevi.

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

Bunu dene

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

Aşağıdaki örnek için çalışıyor

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

0

Peter'ın yanıtı ek bir çekle! Tabii ki% 100 garantili değil!

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!");
}

0

@Martin Wantke cevabına göre, ancak bazı önerilen iyileştirmeler / ayarlamalarla ...

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

}

NOT: Bu yaklaşımı çok öğretici buldum, bu yüzden bu yanıtı gönderdim.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.