다음 예제에서는 JSON 문자열에서 파싱되는 객체를 다시 사용하는 방법을 보여 줍니다. 이 예제에서는 JSONGenericDictExample과 JSONDictionaryExtnExample이라는 두 개의 클래스를 정의하는데, JSONGenericDictExample 클래스는 사용자 정의 사전 클래스입니다. 각 레코드에는 개인의 이름과 생일은 물론 고유한 ID까지 포함되어 있습니다. 생성자 JSONGenericDictExample이 호출될 때마다 해당 ID가 정적으로 증가하는 정수인 내부 정적 배열에 새로 만들어진 객체가 추가됩니다. 또한 JSONGenericDictExample 클래스는 보다 긴
id
멤버에서 정수 부분만 추출하는
revive()
메서드를 정의합니다.
revive()
메서드에서는 이 정수를 사용하여 다시 사용 가능한 올바른 객체를 조회하고 반환합니다.
JSONDictionaryExtnExample 클래스는 ActionScript Dictionary 클래스를 확장합니다. 이 클래스의 레코드에는 설정된 구조가 없으며 어떤 데이터든 포함될 수 있습니다. 데이터는 클래스에서 정의된 속성이라기보다 JSONDictionaryExtnExample 객체가 생성된 후에 할당됩니다. JSONDictionaryExtnExample 레코드에서는 JSONGenericDictExample 객체를 키로 사용합니다. JSONDictionaryExtnExample 객체를 다시 사용하는 경우
JSONGenericDictExample.revive()
함수에서는 JSONDictionaryExtnExample과 연결된 ID를 사용하여 올바른 키 객체를 다시 사용합니다.
무엇보다도,
JSONDictionaryExtnExample.toJSON()
메서드는 JSONDictionaryExtnExample 객체 외에 표시자 문자열을 반환한다는 점이 중요합니다. 이 문자열은 JSON 출력을 JSONDictionaryExtnExample 클래스에 속하는 것으로 식별하는 역할을 합니다. 이 표시자가 있으면
JSON.parse()
가 실행되는 중에 어떤 객체 유형이 처리되고 있는지를 확실히 알 수 있습니다.
package {
// Generic dictionary example:
public class JSONGenericDictExample {
static var revivableObjects = [];
static var nextId = 10000;
public var id;
public var dname:String;
public var birthday;
public function JSONGenericDictExample(name, birthday) {
revivableObjects[nextId] = this;
this.id = "id_class_JSONGenericDictExample_" + nextId;
this.dname = name;
this.birthday = birthday;
nextId++;
}
public function toString():String { return this.dname; }
public static function revive(id:String):JSONGenericDictExample {
var r:RegExp = /^id_class_JSONGenericDictExample_([0-9]*)$/;
var res = r.exec(id);
return JSONGenericDictExample.revivableObjects[res[1]];
}
}
}
package {
import flash.utils.Dictionary;
import flash.utils.ByteArray;
// For this extension of dictionary, we serialize the contents of the
// dictionary by using toJSON
public final class JSONDictionaryExtnExample extends Dictionary {
public function toJSON(k):* {
var contents = {};
for (var a in this) {
contents[a.id] = this[a];
}
// We also wrap the contents in an object so that we can
// identify it by looking for the marking property "class E"
// while in the midst of JSON.parse.
return {"class JSONDictionaryExtnExample": contents};
}
// This is just here for debugging and for illustration
public function toString():String {
var retval = "[JSONDictionaryExtnExample <";
var printed_any = false;
for (var k in this) {
retval += k.toString() + "=" +
"[e="+this[k].earnings +
",v="+this[k].violations + "], "
printed_any = true;
}
if (printed_any)
retval = retval.substring(0, retval.length-2);
retval += ">]"
return retval;
}
}
}
다음 런타임 스크립트가 JSONDictionaryExtnExample 객체에
JSON.parse()
를 호출하면
reviver
함수는 JSONDictionaryExtnExample의 각 객체에
JSONGenericDictExample.revive()
를 호출합니다. 이러한 호출을 통해 객체 키를 나타내는 ID가 추출됩니다.
JSONGenericDictExample.revive()
함수는 이 ID를 사용하여 전용 정적 배열에서 저장된 JSONDictionaryExtnExample 객체를 검색 및 반환합니다.
import flash.display.MovieClip;
import flash.text.TextField;
var a_bob1:JSONGenericDictExample = new JSONGenericDictExample("Bob", new Date(Date.parse("01/02/1934")));
var a_bob2:JSONGenericDictExample = new JSONGenericDictExample("Bob", new Date(Date.parse("05/06/1978")));
var a_jen:JSONGenericDictExample = new JSONGenericDictExample("Jen", new Date(Date.parse("09/09/1999")));
var e = new JSONDictionaryExtnExample();
e[a_bob1] = {earnings: 40, violations: 2};
e[a_bob2] = {earnings: 10, violations: 1};
e[a_jen] = {earnings: 25, violations: 3};
trace("JSON.stringify(e): " + JSON.stringify(e)); // {"class JSONDictionaryExtnExample":
//{"id_class_JSONGenericDictExample_10001":
//{"earnings":10,"violations":1},
//"id_class_JSONGenericDictExample_10002":
//{"earnings":25,"violations":3},
//"id_class_JSONGenericDictExample_10000":
// {"earnings":40,"violations":2}}}
var e_result = JSON.stringify(e);
var e1 = new JSONDictionaryExtnExample();
var e2 = new JSONDictionaryExtnExample();
// It's somewhat easy to convert the string from JSON.stringify(e) back
// into a dictionary (turn it into an object via JSON.parse, then loop
// over that object's properties to construct a fresh dictionary).
//
// The harder exercise is to handle situations where the dictionaries
// themselves are nested in the object passed to JSON.stringify and
// thus does not occur at the topmost level of the resulting string.
//
// (For example: consider roundtripping something like
// var tricky_array = [e1, [[4, e2, 6]], {table:e3}]
// where e1, e2, e3 are all dictionaries. Furthermore, consider
// dictionaries that contain references to dictionaries.)
//
// This parsing (or at least some instances of it) can be done via
// JSON.parse, but it's not necessarily trivial. Careful consideration
// of how toJSON, replacer, and reviver can work together is
// necessary.
var e_roundtrip =
JSON.parse(e_result,
// This is a reviver that is focused on rebuilding JSONDictionaryExtnExample objects.
function (k, v) {
if ("class JSONDictionaryExtnExample" in v) { // special marker tag;
//see JSONDictionaryExtnExample.toJSON().
var e = new JSONDictionaryExtnExample();
var contents = v["class JSONDictionaryExtnExample"];
for (var i in contents) {
// Reviving JSONGenericDictExample objects from string
// identifiers is also special;
// see JSONGenericDictExample constructor and
// JSONGenericDictExample's revive() method.
e[JSONGenericDictExample.revive(i)] = contents[i];
}
return e;
} else {
return v;
}
});
trace("// == Here is an extended Dictionary that has been round-tripped ==");
trace("// == Note that we have revived Jen/Jan during the roundtrip. ==");
trace("e: " + e); //[JSONDictionaryExtnExample <Bob=[e=40,v=2], Bob=[e=10,v=1],
//Jen=[e=25,v=3]>]
trace("e_roundtrip: " + e_roundtrip); //[JSONDictionaryExtnExample <Bob=[e=40,v=2],
//Bob=[e=10,v=1], Jen=[e=25,v=3]>]
trace("Is e_roundtrip a JSONDictionaryExtnExample? " + (e_roundtrip is JSONDictionaryExtnExample)); //true
trace("Name change: Jen is now Jan");
a_jen.dname = "Jan"
trace("e: " + e); //[JSONDictionaryExtnExample <Bob=[e=40,v=2], Bob=[e=10,v=1],
//Jan=[e=25,v=3]>]
trace("e_roundtrip: " + e_roundtrip); //[JSONDictionaryExtnExample <Bob=[e=40,v=2],
//Bob=[e=10,v=1], Jan=[e=25,v=3]>]