Obiekt JavaScript Vs JSON

208

Chcę jasno zrozumieć podstawowe różnice między obiektem JavaScript a łańcuchem JSON.

Załóżmy, że tworzę następującą zmienną JS:

var testObject = {one: 1,"two":2,"three":3};

Pytanie 1 Czy nazwa klucza / właściwości jest poprawna zarówno z / bez cudzysłowów? (np. "one" : 1)

Jeśli tak, jaka jest różnica?

P2: Jeśli przekonwertuję powyższy obiekt za pomocą JSON.stringify(testObject), jaka jest różnica między oryginalnym obiektem JS a JSON?

Czuję, że są prawie takie same. Proszę o rozwinięcie tego.

P3: Czy do parsowania łańcucha JSON zalecana jest poniższa metoda?

var javascriptObj = JSON.parse(jSonString);
testndtv
źródło

Odpowiedzi:

239
  1. Czy nazwa klucza / właściwości jest poprawna zarówno z / bez cudzysłowów?

    Jedynym razem trzeba ująć w cudzysłów klucza przy użyciu Literal Object Notation, gdzie jest klucz zawiera znak specjalny ( if, :, -etc). Warto zauważyć, że klucz w JSON musi być ujęty w podwójne cudzysłowy.

  2. Jeśli przekonwertuję powyższy obiekt na JSON za pomocą var jSonString = JSON.stringify(testObject);, jaka jest różnica między 2 (JS obj i JSON)?

    JSON to format wymiany danych. Jest to standard opisujący, w jaki sposób uporządkowane listy i nieuporządkowane mapy, ciągi logiczne i liczby mogą być reprezentowane w ciągu. Podobnie jak XML i YAML to sposób przekazywania informacji strukturalnych między językami, JSON jest taki sam. Z drugiej strony obiekt JavaScript jest typem fizycznym. Podobnie jak tablica PHP, klasa / struktura C ++, obiekt JavaScript jest rodzajem wewnętrznym dla JavaScript.

    Oto historia. Wyobraźmy sobie, że kupiłeś jakieś meble ze sklepu i chcesz je dostarczyć. W magazynie pozostaje jednak tylko model wyświetlacza, ale zgadzasz się na jego zakup.

    W sklepie zakupiona komoda to żywy przedmiot:

    var chestOfDrawers = {
        color: "red",
        numberOfDrawers: 4
    }
    

    Nie możesz jednak wysyłać komody z postem, więc ją demontujesz (czytaj, szykuj). Jest teraz bezużyteczny pod względem mebli. Teraz jest JSON. Jest w płaskiej formie.

    {"color":"red","numberOfDrawers":4}

    Kiedy je otrzymasz, odbudujesz komodę (przeczytaj, przeanalizuj). Teraz jest z powrotem w formie obiektu.

    JSON / XML i YAML mają na celu umożliwienie przesyłania danych między językami programowania w formacie zrozumiałym dla obu języków uczestniczących; nie możesz podać PHP lub C ++ bezpośrednio swojego obiektu JavaScript; ponieważ każdy język reprezentuje obiekt inaczej pod maską. Ponieważ jednak podzieliliśmy obiekt na notację JSON; tzn. znormalizowany sposób reprezentacji danych, możemy przesłać reprezentację JSON obiektu do innego języka (C ++, PHP), mogą odtworzyć obiekt JavaScript, który mieliśmy w swoim własnym obiekcie, w oparciu o reprezentację JSON obiektu.

    Należy zauważyć, że JSON nie może reprezentować funkcji ani dat. Jeśli spróbujesz skreślić obiekt za pomocą elementu funkcji, funkcja zostanie pominięta w reprezentacji JSON. Data zostanie przekonwertowana na ciąg;

    JSON.stringify({
        foo: new Date(),
        blah: function () { 
            alert('hello');
        }
    }); // returns the string "{"foo":"2011-11-28T10:21:33.939Z"}"
    
  3. Czy do parsowania łańcucha JSON zalecana jest poniższa metoda? var javascriptObj = JSON.parse(jSonString);

    Tak, ale starsze przeglądarki nie obsługują natywnie JSON (IE <8) . Aby je wesprzeć, należy dołączyć json2.js.

    Jeśli używasz jQuery, możesz zadzwonić jQuery.parseJSON(), który użyje JSON.parse()pod maską, jeśli jest obsługiwany, a w przeciwnym razie wróci do niestandardowej implementacji, aby przeanalizować dane wejściowe.

Matt
źródło
4
@testndtv brakuje Ci sensu - chociaż na papierze (lub na ekranie) ciąg JSON i wyświetlanie obiektu JS mogą wyglądać tak samo, to nie to samo. JSON to tylko sposób na spakowanie obiektu do łańcucha, dzięki czemu można go gdzieś przenieść, a następnie rozpakować z powrotem do obiektu.
Alnitak
1
@Matt słaba analogia IMHO - JSON nie powinien być używany do serializacji obiektu, który ma metody - tylko dla czystych obiektów danych.
Alnitak
1
Więc jeśli obiekt JS ma metody, to czy konwersja na ciąg JSON całkowicie go zignoruje ... tak jak w powyższym przypadku getIn i getOut zostaną całkowicie zignorowane ... Czy tak to działa?
testndtv
3
@ Grrowler: zwykle używam JSON, jeśli „rzecz” musi zostać wygenerowana na serwerze, i używam pliku js, jeśli „rzecz” jest po prostu serwowana w niezmienionej postaci. Innym dużym wyróżnikiem jest to, czy musisz uwzględnić funkcje i / lub daty, ponieważ JSON nie może ich reprezentować, więc musisz skorzystać z udostępniania pliku JS. Jeśli nadal nie masz pewności, zadaj to pytanie jako osobne pytanie na temat Przepełnienia stosu (pokaż przykład treści, którą musisz podać, aby reprezentować swoje okno dialogowe), i podaj mi link; Z przyjemnością przyjrzę się bliżej!
Matt
4
@Matt You, proszę pana, jesteś genialnym królem! Twoje wyjaśnienie jest precyzyjne, jasne, zwięzłe i łatwe do zrozumienia. Chciałbym, żebyś był moim mentorem JavaScript / programowania.
FrankDraws,
30

P1: Podczas definiowania literałów obiektów w javascript klucze mogą zawierać cudzysłowy lub nie. Nie ma żadnej różnicy, z wyjątkiem tego, że cudzysłowy pozwalają określić pewne klucze, które spowodowałyby, że interpreter nie mógłby się sparować, gdybyś wypróbował je same. Na przykład, jeśli chcesz klucz, który był tylko wykrzyknikiem, potrzebujesz cudzysłowów:

a = { "!": 1234 } // Valid
a = { !: 1234 } //  Syntax error

Jednak w większości przypadków można pominąć cudzysłowy wokół klawiszy na literałach obiektów.

Q2: JSON jest dosłownie ciągiem znaków. To tylko struna. Rozważ to:

var testObject = { hello: "world" }
var jSonString = JSON.stringify(testObject);

Ponieważ testObjectjest to prawdziwy obiekt, możesz wywoływać na nim właściwości i robić wszystko, co możesz zrobić z obiektami:

testObject.hello => "world"

Z drugiej strony jsonStringjest tylko ciągiem znaków:

jsonString.hello => undefined

Zauważ jeszcze jedną różnicę: w JSON wszystkie klucze muszą być cytowane. Kontrastuje to z literałami przedmiotowymi, w których cytaty można zwykle pominąć zgodnie z moim wyjaśnieniem w Q1.

Pytanie 3 Możesz parsować ciąg JSON za pomocą JSON.parse, i jest to ogólnie najlepszy sposób, aby to zrobić (jeśli przeglądarka lub środowisko to zapewnia). Możesz także użyć, evalponieważ JSON jest poprawnym kodem javascript, ale poprzednia metoda jest zalecana z wielu powodów (eval ma z sobą wiele nieprzyjemnych problemów).

Ben Lee
źródło
9

Problemy rozwiązane przez JSON

Załóżmy, że chcesz wymieniać zwykłe obiekty JavaScript między dwoma komputerami i ustawisz dwie reguły:

  • Przesyłane dane muszą być ciągiem zwykłym.
  • Można wymieniać tylko atrybuty, metody nie są przesyłane.

Teraz tworzysz dwa obiekty na pierwszym hoście:

var obj1 = { one: 1,"two":2,"three":3 }; // your example
var obj2 = { one: obj1.one, two: 2, three: obj1.one + obj1.two };

Jak przekonwertować te obiekty na ciągi w celu transmisji do drugiego hosta?

  • W przypadku pierwszego obiektu możesz wysłać ten ciąg uzyskany z definicji literału '{ one: 1,"two":2,"three":3 }', ale tak naprawdę nie możesz odczytać literału w części skryptu dokumentu (przynajmniej nie łatwo). Tak obj1i obj2rzeczywiście muszą być przetwarzane w ten sam sposób.
  • Musisz wyliczyć wszystkie atrybuty i ich wartość oraz zbudować ciąg podobny do literału obiektu.

JSON został stworzony jako rozwiązanie właśnie omawianych potrzeb: jest to zestaw reguł do tworzenia ciągu równoważnego z obiektem poprzez wyświetlenie wszystkich atrybutów i wartości (metody są ignorowane).

JSON normalizuje użycie podwójnych cudzysłowów dla nazw i wartości atrybutów.

Pamiętaj, że JSON jest tylko zbiorem reguł (standard).

Ile obiektów JSON zostało utworzonych?

Tylko jeden jest automatycznie tworzony przez silnik JS.

Nowoczesne silniki JavaScript znalezione w przeglądarkach mają obiekt macierzysty, zwany także JSON. Ten obiekt JSON może:

  • Dekoduj ciąg zbudowany przy użyciu standardu JSON, używając JSON.parse (ciąg). Wynikiem jest zwykły obiekt JS z atrybutami i wartościami znalezionymi w ciągu JSON.

  • Zakoduj atrybuty / wartości zwykłego obiektu JS za pomocą JSON.stringify (). Wynikiem jest ciąg zgodny z zestawem reguł JSON.

(Pojedynczy) obiekt JSON jest podobny do kodeka, jego funkcją jest kodowanie i dekodowanie.

Uwaga:

  • JSON.parse () nie tworzy obiektu JSON, tworzy zwykły obiekt JS, nie ma różnicy między obiektem utworzonym za pomocą literału obiektu a obiektem utworzonym przez JSON.parse () z łańcucha zgodnego z JSON.

  • Jest tylko jeden obiekt JSON, który jest używany do wszystkich konwersji.

Wracając do pytań :

  • P1: W przypadku literałów obiektowych dozwolone jest stosowanie pojedynczego podwójnego cudzysłowu. Zauważ, że cudzysłowy są używane opcjonalnie dla nazw atrybutów i są obowiązkowe dla wartości ciągu. Sam dosłowny obiekt nie jest otoczony cudzysłowami.

  • Q2: Obiekty utworzone z literałów i przy użyciu JSON.parse () są dokładnie takie same. Te dwa obiekty są równoważne po utworzeniu:

    var obj1 = { one: 1, "two": 2, "three": 3 };
    var obj2 = JSON.parse('{ "one": "1", "two": "2", "three": "3" }');

  • P3: W nowoczesnych przeglądarkach JSON.parse()jest używany do tworzenia obiektu JS z ciągu zgodnego z JSON. (jQuery ma również równoważną metodę, której można używać we wszystkich przeglądarkach).

min
źródło
7

Q1 - w JS musisz używać cudzysłowów tylko wtedy, gdy klucz jest słowem zastrzeżonym lub jeśli w przeciwnym razie byłby to nielegalny token. W JSON MUSISZ zawsze używać podwójnych cudzysłowów przy nazwach kluczy.

Q2 - jsonStringto serializowana wersja obiektu wejściowego ...

Q3 - który można przekształcić do postaci szeregowej za pomocą identycznie wyglądającego obiektuJSON.parse()

Alnitak
źródło
1

Pytanie ma już dobre odpowiedzi, poniżej dodaję mały przykład, który ułatwi zrozumienie wyjaśnień podanych w poprzednich odpowiedziach. Skopiuj wklej poniżej fragmentu do IDE, aby lepiej zrozumieć i skomentuj wiersz zawierający invalid_javascript_object_no_quotesdeklarację obiektu, aby uniknąć błędu czasu kompilacji.

// Valid JSON strings(Observe quotes)
valid_json = '{"key":"value"}'
valid_json_2 = '{"key 1":"value 1"}' // Observe the space(special character) in key - still valid


//Valid Javascript object
valid_javascript_object_no_quotes = {
    key: "value"  //No special character in key, hence it is valid without quotes for key
}


//Valid Javascript object
valid_javascript_object_quotes = {
    key:"value",  //No special character in key, hence it is valid without quotes for key
    "key 1": "value 1" // Space (special character) present in key, therefore key must be contained in double quotes  - Valid
}



console.log(typeof valid_json) // string
console.log(typeof valid_javascript_object_no_quotes) // object
console.log(typeof valid_javascript_object_quotes) // object

//Invalid Javascript object 
invalid_javascript_object_no_quotes = {
   key 1: "value"//Space (special character) present in key, since key is not enclosed with double quotes "Invalid Javascript Object"
}
siedmiodniowa żałoba
źródło