먼저 얕은 복사의 결함을 살펴보겠습니다. 얼마나 많은 사람들이 이 트릭의 희생양이 되었습니까?
var oOriginal = {
memNum: 1, / / 숫자
memStr: "I am a string", // 문자열
memObj: {
test1: "이전 값" // 테스트하겠습니다
},
memArr : [ / / 배열
"a string", // 배열의 문자열 멤버
{ // 배열의 객체 멤버
test2: "Try Changing me" // 테스트해 보겠습니다
}
]
};
객체와 배열을 포함하는 비교적 복잡한 객체입니다. Prototype의 유명한 상속 기능을 사용하여 조금 더 복잡하게 만들어 보겠습니다. 상속이라고 말하기는 어렵고 jQuery도 포함되지 않습니다.
var extend = function(result, source) {
for(소스의 var 키)
result[key] = source[key];
return result;
}
테스트 프로그램:
var oCopy = extend({},oOriginal) // Shallow copy
oCopy .memObj.test1 = "New value"; // 문제가 발생하면 원본 객체에 반영됩니다.
alert(oOriginal.memObj.test1); 원본이 함께 수정되었습니다
oCopy.memArr[1].test2 = "나는 변경되었습니다"
alert(oOriginal.memArr[1].test2) // 또한
]
원본 개체를 수정하지 않으려면 개체와 배열을 특별히 처리해야 하는 것 같습니다. 그들을 다루기 위해서는 그들을 식별해야 합니다. 다음 함수를 살펴보세요.
코드는 다음과 같습니다.
/* *
* 유형 식별 - By Situ Zhengmei::cheng(MIT 라이센스)
* http://www.cnblogs.com/rubylouvre/archive/2010/01/20/1652646.html
*/
var is = function (obj,type) {
var toString = Object.prototype.toString,undefine;
return (type === "Null" && obj === null)
(유형 === "정의되지 않음" && obj === 정의되지 않음 ) ||
toString.call(obj).slice(8,-1) === 유형; ;
위 함수는 유형 식별에 사용됩니다. 배열은 "객체"를 반환하지 않으며 다른 문서 개체의 배열 인스턴스도 확인할 수 없습니다. Object.prototype.toString.call을 사용하는 것이 완벽하지는 않지만 duck 유형은 복사하기 쉽지만 이전보다 훨씬 안정적입니다.
공식적으로 주제를 입력해 보겠습니다. 우리의 깊은 복사 기능은 값이 객체와 배열인 키-값 쌍을 특별히 처리합니다. 이를 위해 프로그램은 먼저 대상 객체에 대한 새 객체와 배열을 생성한 다음 복사합니다. 그것들을 층층이 쌓아올려요. hasOwnProperty를 사용하지 않는 것을 볼 수 있습니다. 즉, 프로토타입의 탐색 가능한 속성조차 거꾸로 되어 있다는 것을 알 수 있습니다. 배열의 경우 for(,,,) 루프를 사용하지 않습니다. 괄호 안의 요소만 반복할 수 있고 배열에 연결된 다른 속성을 통해 반복할 수 없습니다. 따라서 for...in의 방법은 매우 느립니다. 여기에는 여전히 필요합니다. 딥카피는 모든 속성을 확인하고 중간에 새로운 객체를 생성할 수도 있기 때문에 무거운 방식이다. 할 일이 없다면 사용하지 마세요.
/**
* type identification - By 司徒正美::cheng (MIT Licensed)
* http://www.cnblogs.com/rubylouvre/archive/2010/03/26/1696600.html
*/
dom.deepCopy = function(result, source){
for(var key in source) {
var copy = source[key];
if(result === copy) continue;//如window.window === window,会陷入死循环,需要处理一下
if(dom.is(copy,"Object")){
result[key] = arguments.callee(result[key] || {}, copy);
}else if(dom.is(copy,"Array")){
result[key] = arguments.callee(result[key] || [], copy);
}else{
result[key] = copy;
}
}
return result;
};
作者:司徒正美