2013-03-31 23 views
6

mam szeregowania obiektów do ciągów JSON z JavaScript,Dlaczego funkcja JSON.stringify nie jest serializowaniem właściwości nieprzeliczalnych?

Zauważyłem tylko przeliczalne właściwości obiektu dostać odcinkach:

var a = Object.create(null,{ 
    x: { writable:true, configurable:true, value: "hello",enumerable:false }, 
    y: { writable:true, configurable:true, value: "hello",enumerable:true } 
}); 
document.write(JSON.stringify(a)); //result is {"y":"hello"} 

[pen]

Zastanawiam się dlaczego tak jest? Przeszukałem dokumentację parsera MDN page, json2. Nie można znaleźć tego zachowania udokumentowanego gdziekolwiek.

Podejrzewam, że jest to wynik użycia pętli for... in, które mają właściwości only go through [[enumerable]] (przynajmniej w przypadku json2). Można to prawdopodobnie zrobić za pomocą czegoś takiego jak Object.getOwnPropertyNames, które zwraca zarówno właściwości przeliczalne, jak i nieprzeliczalne. To może być problematyczne z serializowaniem (z powodu deserializacji).

tl; dr

  • Dlaczego JSON.stringify tylko serializacji właściwości przeliczalny?
  • Czy to zachowanie jest udokumentowane w dowolnym miejscu?
  • Jak samodzielnie zaimplementować szeregowanie właściwości nieprzeliczalnych?
+0

Jeśli ustawisz wyliczenie na wartość false, nie będzie dodawana żadna instancja. Wypróbuj konsolę, rejestrując obiekt przed jego ufiksowaniem, a zobaczysz, że 'x' nie ma w samym obiekcie, więc z pewnością nie może być tam, kiedy jest uszeregowany. – adeneo

+0

@adeneo to prawdopodobnie dlatego, że używa również czegoś takiego jak stringify, a nie getOwnPropertyNames. Object.getOwnPropertyNames (a) zwraca ["x", "y"] i jeśli wpiszesz obj.x otrzymasz "cześć". –

+0

Tak, zauważyłem, i to jest dobra wskazówka, że ​​prawdopodobnie powinieneś rozważyć i znaleźć inny sposób tworzenia obiektu. – adeneo

Odpowiedz

9

Jest on określony w ES5 spec.

Jeśli typ (wartość) jest obiekt i IsCallable (wartość) jest fałszywe

If the [[Class]] internal property of value is "Array" then 

    Return the result of calling the abstract operation JA with argument value. 

Else, return the result of calling the abstract operation JO with argument value. 

Więc spójrzmy na JO. Oto odnośny rozdział:

Niech K będzie wewnętrzną listą ciągów składających się z nazwiskami wszystkich wartości własnych właściwości którego [[Enumerable]] atrybut jest prawdą. Kolejność łańcuchów powinna być taka sama, jak w standardowej wbudowanej funkcji Object.keys.

+1

Ah, nie miałem pojęcia, że ​​stringify jest częścią specyfikacji, to jest dokładnie to, czego szukałem, dzięki. –

Powiązane problemy