일반 object clone

황제낙엽 2011.07.08 17:44 조회 수 : 2176

sitelink1 http://blog.imaginea.com/deep-copy-in-javascript/ 
sitelink2  
sitelink3  
sitelink4 http://1 
extra_vars4 ko 
extra_vars5  
extra_vars6 sitelink1 
 

Some of you might have come across this issue. When you make a copy of an object and try to change the values of the new instance, it reflects in the original one too. Well I heard this not only applies to JavaScript, but also to most other object oriented languages; not sure though.

Here is a case:

Problem
//original object definition
var oOriginal = {
    memNum: 1,                                        // number
    memStr: "I am a string",                          // string
    memObj: {
        test1: "Old value"                            // we'll test
    },
    memArr: [                                         // array with object members
        "a string",                                   // simple string element
        {                                             // an object
            test2: "Try changing me"                  // we'll test
        }
    ]
};

//test 1
var oCopy = oOriginal;                                // normal copy

oCopy.memObj.test1 = "New value";                     // Problem
                                                      // - will reflect in oOriginal

alert(oOriginal.memObj.test1);                        // will show "New value"

//test 2
oCopy.memArr[1].test2 = "I am changed";               // Problem
                                                      // - will reflect in oOriginal

alert(oOriginal.memArr[1].test2);                     // will show "I am changed"

 

 

Here the problem is, the objects are never copied, only their references are. So what’s the solution? Iterate through all members of the original object, create the same members for target object and then assign corresponding values. And while doing so, we can’t forget array of objects.

We’ll add this simple line at the very top to help us detect Array objects. It basically adds our own custom extension to the Array class.

To recognize Array type objects
<html>
<head>
<title>Deep Copy in JavaScript</title>
<script language="javascript" type="text/javascript">
    Array.prototype.__isArray = true;
</script>
.
.

 

 

Now, here is the generic method that will help in iterating through all (type of) members of our original object and copy them one-by-one regardless of the depth of the object structure:

Solution
var ObjectHandler = {
    //public method
    getCloneOfObject: function(oldObject) {
        var tempClone = {};

        if (typeof(oldObject) == "object")
            for (prop in oldObject)
                // for array use private method getCloneOfArray
                if ((typeof(oldObject[prop]) == "object") &&
                                (oldObject[prop]).__isArray)
                    tempClone[prop] = this.getCloneOfArray(oldObject[prop]);
                // for object make recursive call to getCloneOfObject
                else if (typeof(oldObject[prop]) == "object")
                    tempClone[prop] = this.getCloneOfObject(oldObject[prop]);
                // normal (non-object type) members
                else
                    tempClone[prop] = oldObject[prop];

        return tempClone;
    },

    //private method (to copy array of objects) - getCloneOfObject will use this internally
    getCloneOfArray: function(oldArray) {
        var tempClone = [];

        for (var arrIndex = 0; arrIndex <= oldArray.length; arrIndex++)
            if (typeof(oldArray[arrIndex]) == "object")
                tempClone.push(this.getCloneOfObject(oldArray[arrIndex]));
            else
                tempClone.push(oldArray[arrIndex]);

        return tempClone;
    }
};

 

 

Now we’ll perform the same two tests mentioned in the ‘Problem’ block using this new helper – ObjectHandler

Test
//test 1
var oCopy = ObjectHandler.getCloneOfObject(oOriginal);

oCopy.memObj.test1 = "New value";

alert(oOriginal.memObj.test1);                        // will show "Old value"

//test 2
oCopy.memArr[1].test2 = "I am changed";

alert(oOriginal.memArr[1].test2);                     // will show "Try changing me"

 

 

In general, this solution is often referred to as "Deep Copy".

번호 제목 글쓴이 날짜 조회 수
146 JavaScript Form Validation file 황제낙엽 2008.11.24 495
145 innerHTML 황제낙엽 2005.12.19 495
144 비동기프로그래밍 - 콜백함수(Callback function) file 황제낙엽 2020.08.26 494
143 크로스 브라우저를 위한 브라우저 검사 코드 file 황제낙엽 2010.08.27 490
142 아이디 생성 조건 검사 자바스크립트 모듈 황제낙엽 2004.11.18 490
141 익스플로러용 스크립트 디버거 (Script Debugger for Windows NT 4.0 and Later) 황제낙엽 2008.12.11 489
140 DOM과 innerHTML 방법에 대한 비교 분석 황제낙엽 2008.11.03 485
139 JAVASCRIPT REFERENCE 파일 file 황제낙엽 2005.11.22 485
138 자바스크립트 숫자형 체크 함수 (isFinite() 함수 와 isNaN() 함수) 황제낙엽 2011.12.13 484
137 자동 형변환 (문자열 -> 숫자) 황제낙엽 2009.06.25 483
136 마우스 오버시 살짝 뒤로 물러나는 듯한 링크 -_-;; 황제낙엽 2003.01.04 482
135 int * float 연산 오류 file 황제낙엽 2008.12.11 481
134 재사용 가능한 일회용 객체 황제낙엽 2008.08.08 479
133 State of ECMAScript 4 ('07 12) 황제낙엽 2008.07.14 477
132 |= 비트 OR 대입 연산자 (복합대입연산자) 황제낙엽 2017.03.15 477
131 [JavaScript Tutorials] Error handling in JavaScript using try/catch/finally - The Error object and throwing your own errors (해석중) 황제낙엽 2009.04.10 474
130 [URLSearchParams] URL 파라미터(매개변수) 값 가져오기 file 황제낙엽 2023.02.02 473
129 폼으로 XML 데이터 전송 (JSP+Javascript) 황제낙엽 2005.12.04 473
128 delete 연산자에 대한 고찰 황제낙엽 2012.06.11 472
127 HTTP Content-Type 정리 황제낙엽 2013.09.30 471