JSON은 javascript상의 객체정보를 문자열로 저장하고,
이를 기반으로 빠르게 객체구조를 작성하도록 해주는
에드온 스크립트라고 할 수 있습니다.
비교적 간단하게 사용할 수 있고, 범용성도 높지만
치명적인 단점이 하나 있으니... loop식으로 방문하는
고리구조의 객체 데이터 참조를 하게 될 경우에
발생하는 Object Too Deep 오류입니다.
JSON parser로 객체를 문자열로 변환할 때에
상위 객체와 하위 객체가 서로의 메모리 주소를
가리키는 직접적인 데이터 참조가 가능하도록
객체에 종속되어 있는 변수에 저장하게 되면
[ ※ 아래는 고리구조 객체 데이터 참조의 예일뿐입니다. ※ ]
[ ※ 최적화시키는 방식에 대해서는 추가로 다루지 않습니다.※ ]
var mcount = 9999;
function item_(parent, item_id){
this.parent = parent;
this.item_id = item_id;
this.name;
this.category;//아이템의 분류
this.weight;
this.size;
this.count;
this.init = function init(item_count){
var info = item_find(this.item_id);
this.name = info[0];
this.category = info[1];
this.weight = info[2];
this.size =info[3];
this.count = item_count;
};
this.adjust_count = function adjust_count(isplus,v){
switch(isplus){
case 1://this.count + v 일 때
switch(this.count + v <= mcount){
case true://mcount 값보다 작거나 같으면
this.count += v;
break;
default://mcount 값보다 크면
this.count = mcount + 0;
break;
}
break;
case 0://this.count - v 일 때
switch(this.count - v > -1){
case true://-1 보다 크면
this.count -= v;
break;
default://-1 보다 작거나 같으면
this.count = 0;
break;
}
break;
};
};
//객체 생성자는 원본 객체를 가리킴
item_.prototype.constructor = item_;
function material_(){
this.mcategory;//재질의 분류
this.mattribute;//재질의 속성
this.meltingpoint;//용융점
this.minit = function minit(material_count){
var info = material_find(this.item_id);
this.mcategory = info[0];
this.mattribute = info[1];
this.meltingpoint = info[2];
this.init(material_count);//상속받은 item객체의 init()함수 실행
};
};
//객체 확장 / 상속
material_.prototype = new item_();
//객체 생성자는 원본 객체를 가리킴
material_.prototype.constructor = material_;
function recipe_(recipe_id){
this.recipe_id = recipe_id;
this.list = new Array();
this.init = funciton init(){
var i, j,recipe_string;
recipe_string = recipe_find(this.recipe_id);
switch(typeof recipe_string === "string"){
case true:
i = recipe_string.split("/");
for(j = 0;j < i.length;j++){
this.list.push(i[j].split(","));
}
for(j = 1j < this.list[1].length;j++){
//this.list[0][0]에는 조합법의 이름이 존재해야 한다고 가정
//this.list[1] 에는 material_ 객체의 참조 데이터 배열가 존재해야 한다고 가정
//this.list[2] 에는 필요한 수량 데이터 배열이 존재해야 한다고 가정
//고리구조 객체 데이터 참조 부분
this.list[1][j] = new material_(this,this.list[1][j]);
}
break;
default:
//에러문 출력
throw new Error(" : 조합법 문자열이 잘못되었습니다.\n올바른 문자열을 입력해주세요");
break;
}
};
};
recipe_.prototype.constructor = recipe_;
레시피를 통해 아이템이나 기타 등등을
재료를 참조해서 알고자 할 때에 위와 같이
작성할 수 있다고 가정해보았습니다.
recipe_의 상위객체에도 list가 있어서
recipe_의 인스턴스 객체들을 관리한다고 할 때애
굳이 .parent 변수에 recipe_ 인스턴스 객체를
가르킬 필요없이 recipe_id 만 알 수 있더라도
상위 객체에서 .list를 통해서 접근할 수 있다는
점은 조금만 생각해보셔도 아실 수 있습니다.
위와 같이 추가적으로 객체나 개체를 추가하는
스크립트를 작성하게 되는 원인은시스템이 어떻게
구현되어 있는지 알지 못하기 때문입니다.
위와 같이 상위 - 하위 객체간 직접적인 객체의
데이터 참조를 위한 스크립트의 작성은 구조를
알고, 에러가 나지 않게 끔 작성을 해둔 상태라면
recipe_id 를 참조 데이터로 따로 알 수 있도록
해둔 경우에 아래와 같이 접근해서 알 수 있을 겁니다.
게임시스템객체.조합법리스트[recipe_id].list[0]
JSON을 통한 객체->문자열 세이브 방식을
채용한 시스템에 스크립트를 추가/수정할 때에는
.변수 = this;
와 같은 형식의 작성은 피해주어야 합니다.
JSON은 상/하위를 통틀어 중복의 검사는
하지 않기에 각 객체에 유효한 키 데이터로
접근하는 방식으로 수정해주시면 JSON에서의
Obejct Too Deep 에러는 발생하지 않습니다.