본문 바로가기
IT/JavaScript

삭제된 스크립트의 코드는 수행할 수 없습니다. (feat. deep copy 속도 비교)

by 최고영회 2019. 5. 30.
728x90
반응형
SMALL

JavaScript Object 대입은 '참조' 이다. 

var orgObj = {name:'kim', hobby:'singing'};
var copyObj = orgObj;
copyObj.hobby = 'listening';
console.log(orgObj);
console.log(copyObj);

위 코드에서 결과는 둘다 {name: "kim", hobby : "listening"} 이 된다.  참조이기 때문에...

그래서 우리는 deep copy 를 통해 JavaScript 의 Object 를 copy 한다. 

프로젝트를 수행하다 보니 예상치 못한 곳에서 deep copy 가 필요한 것을 확인 했다. 

상황은 이렇다. 

1. A.jsp 에 iframe 이 있다. 
2. A.jsp 에서 특정 버튼 클릭 시 iframe 을 jquery dialog 로 띄우면서 iframe 내에 있는 form 을 submit 한다. 
3. submit 의 결과는 B.jsp 이다.
4. 즉, A.jsp 에서 띄운 dialog 는 B.jsp 이다. 
5. dialog 에서 데이터들을 선택하고 '확인' 하면 parent.choiceData(obj); 로 A.jsp 에 Object 를 전달한다. 
6. A.jsp 의 choiceData(obj) 에서는 $userAcct.authInfo = obj.authInfo.map; 으로 B.jsp 가 보내준 데이터를 대입하고
   dialog 를 close 한다. 

그런데 이후에 $userAcct.autuInfo 를 이용하는 곳에서 <삭제된 스크립트의 코드는 수행할 수 없습니다.> 라는 에러가 발생한다. 

참조의 원본이 되었던 B.jsp 의 Object 가 dialog 가 close 되는 시점에 window 에서 삭제 되었기 때문에 문제가 발생한 것이다. 

그래서 A.jsp 의 choiceData(obj) 함수를 아래와 같이 변경 하여 해결 한다.

// 수정본
function choiceData(copyObj) {
	var obj = jQuery.extend(true, {}, copyObj); 
	userAcct.userInfo = obj.authInfo.map;
    // ... 생략 
    $('#choiceDataPop').dialog('close');
}



// 원본
function choiceData(obj) {
	userAcct.userInfo = obj.authInfo.map;
    // ... 생략 
    $('#choiceDataPop').dialog('close');
}

그런데 이 문제는 IE에서만 발생한다....
Chrome 에서는 jQuery dialog 가 close 될 때 참조 원본의 Object 가 삭제되면 자동으로 Deep Copy 가 이루어지는 건지는 모르겠으나 .... IE에서만 발생한다. (역시 IE..)

Deep Copy 방식

Deep Copy 하는 방법은 다양하다. 위의 코드에서는 jquery의 extend() 를 이용하였다. 

사실 jQuery.extend()는 다른 방식들에 비해 느린 편이다. 

Chrome 에서 테스트 해 보면

ES5 Object.clone > angular.copy() > jQuery.extend() > JSON stringfy/parse > stringfy eval 순서가 나오며 

IE 에서 테스트 해 보면

ES5 Object.clone > aungualr.copy() > stringify eval > JSON stringify/parse > jQuery.extend() 순서가 나온다...

728x90
반응형
LIST