프로그래밍/Web Frontend
[리펙토링] 씬그래프 오브젝트 레퍼런싱 및 Javascript/Typescript 의 Call by reference
초코렡바
2018. 6. 5. 12:00
일단 결론부터 이야기하면 자바스크립트는 Call by value이다.
파라메터로 넘길때는 해당 내용을 복사해서 넘기며 이전 콜스택으로 돌아오면
해당 내용이 변경되지 않는다.
아래 내용은 유니티나 코코스에서 씬링크를 걸때 씬에서 링크를 걸면
서로 작업간에 씬 머지나 메타파일에 문제가 생기면 링크가 깨지는 문제 때문에
직접 코드에서 찾아서 해주는 코드이다.
장점이 있는 반면 코드의 량이 많아지는 문제가 있기 때문에 줄이기 위해서 매번 노력한다.
C#은 ??라는 오퍼레이터가 있었기 때문에 조금더 짧게 코딩 할 수 있었다.
물론 자바스크립트로 ||가 있기때문에 비슷한 양의 코드로 해결 가능했다.
export class BetMoney
_label: cc.Label;
get label(): cc.Label {
if (this._label === undefined) {
this._label = this.node.getChildByName('label').getComponent<cc.Label>(cc.Label);
}
return this._label;
}
하지만 좀더 줄여보고 싶어서
아래 코드를 작성 했지만 밸류처럼 T를 넘길 수 없었다.
//
function getChild<T extends cc.Component>(target: T, parent: cc.Node, childName: string): T {
if (target !== undefined) { return target; }
target = parent.getChildByName(childName).getComponent<T>(T); // 맨뒤의 (T)가 오류
return target;
}
그래서 스페셜라이즈 해서 작업을 해서 아래 코드가 되었다.
//
function getChildLabel(parent: cc.Node, childName: string): T {
if (target !== undefined) { return target; }
target = parent.getChildByName(childName).getComponent<cc.Label>(cc.Label);
return target;
}
export class BetMoney
_label: cc.Label;
get label(): cc.Label {
// this._label에 저장되지 않아서 매번 찾음
return getChildLabel(this._label, this.node, 'label');
}
}
하지만 또다른 복병이 있었으니 자바스크립트 Call By Value로 인해서
this._label이 저장되어있지 않다보니 매번 찾았다.
//
function getChildLabel(parent: cc.Node, childName: string): T {
target = parent.getChildByName(childName).getComponent<cc.Label>(cc.Label);
return target;
}
export class BetMoney
_label: cc.Label;
get label(): cc.Label {
if (this._label === undefined) {
this._label = getChildLabel(this.node, 'label');
}
return this._label;
}
}
그래서 C#의 ?? 처럼 한번 축약 더 해볼 수 있다.
//
function getChildLabel(parent: cc.Node, childName: string): T {
target = parent.getChildByName(childName).getComponent<cc.Label>(cc.Label);
return target;
}
export class BetMoney
_label: cc.Label;
get label(): cc.Label {
return this._label || (this._label = getChildLabel(this.node, 'label'));
}
}
하지만 최종적으로는 아래처럼 되었다.
export class BetMoney
_label: cc.Label;
get label(): cc.Label {
return this._label || (this._label = this.node.getChildByName('label').getComponent<cc.Label>(cc.Label));
}
}
용법을 변경해가면서 까지 축약할 정도는 되지 않았기 때문이다.