>  기사  >  웹 프론트엔드  >  js 객체의 얕은 복사와 깊은 복사에 대한 자세한 설명

js 객체의 얕은 복사와 깊은 복사에 대한 자세한 설명

高洛峰
高洛峰원래의
2017-01-03 15:57:121248검색

본 글에서는 참고용으로 자바스크립트 객체의 얕은 복사와 깊은 복사 코드를 공유합니다.

1. 얕은 복사는

복사란 해당 개체의 속성을 복사하는 것입니다. 상위 개체에 모두 복사됩니다.

다음 기능은 복사중입니다.

var Chinese = {
  nation:'中国'
}
var Doctor = {
  career:'医生'
}  
function extendCopy(p) {
    var c = {};
    for (var i in p) { 
      c[i] = p[i];
    }
    c.uber = p;
    return c;
 }

사용시에는 이렇게 적어주세요.

var Doctor = extendCopy(Chinese);
Doctor.career = '医生';
alert(Doctor.nation); // 中国

그런데 이렇게 복사하는데 문제가 있습니다. 즉, 부모 객체의 속성이 배열이나 다른 객체와 같다면 실제로 자식 객체가 얻는 것은 실제 복사본이 아닌 메모리 주소뿐이므로 부모 객체가 조작되었습니다.

이제 중국어에 "출생지" 속성을 추가하세요. 해당 값은 배열입니다.

Chinese.birthPlaces = ['Beijing','Shanghai','Hong Kong'];

extendCopy() 함수를 통해 Doctor는 중국어를 상속받습니다.

var Doctor = extendCopy(중국어);

그런 다음 Doctor의 "출생지"에 도시를 추가합니다.

Doctor.birthPlaces.push('Xiamen') ;

입력 결과 보기

alert(Doctor.birthPlaces); //Beijing, Shanghai, Hong Kong, Xiamen
alert(China.birthPlaces) //Beijing, Shanghai, Hong 쿵, 샤먼

결과적으로 두 사람의 출생지가 모두 변경되었습니다.

그래서, extendCopy()는 기본 유형의 데이터만 복사합니다. 우리는 이 복사본을 "얕은 복사본"이라고 부릅니다.

2. Deep Copy

Shallow Copy와 Deep Copy에는 이런 단점이 있기 때문에 Deep Copy를 살펴보겠습니다

소위 Deep Copy는 가능하다는 뜻입니다. 배열과 객체의 실제 복사본을 얻습니다. 구현은 어렵지 않습니다. 그냥 "shallow copy"를 재귀적으로 호출하면 됩니다.

function deepCopy(p, c) {
    var c = c || {};
    for (var i in p) {
      if (typeof p[i] === 'object') {
        c[i] = (p[i].constructor === Array) ? [] : {};
        deepCopy(p[i], c[i]);
      } else {
         c[i] = p[i];
      }
    }
    return c;
  }

사용 방법 살펴보기:

var Doctor = deepCopy(중국어);

이제 값을 사용하여 상위 개체에 속성을 추가합니다. 정렬. 그런 다음 하위 개체에서 이 속성을 수정합니다.

Chinese.birthPlaces = ['北京','上海','香港'];
Doctor.birthPlaces.push('厦门');
 
alert(Doctor.birthPlaces); //北京, 上海, 香港, 厦门
alert(Chinese.birthPlaces); //北京, 上海, 香港

이렇게 하면 복사가 완료됩니다.

$.extend()

jquery의 $.extend()는 다음과 같습니다. .

$.extend( [deep ], target, object1 [, objectN ] )

•deep
유형: 부울
true인 경우 재귀로 병합( 또한 딥 카피라고 함).
•target
유형: 객체
객체 확장자. 그러면 새 속성이 수신됩니다.
•object1
유형: Object
첫 번째 매개변수에 병합된 추가 속성을 포함하는 개체
•objectN
유형: 첫 번째 매개변수에 병합된 추가 속성을 포함하는
매개변수 1개

$.extend()에 두 개 이상의 객체를 제공하면 객체의 모든 속성이 대상 객체(대상 매개변수)에 추가됩니다.

$.extend()에 인수가 하나만 제공되면 대상 인수가 생략된다는 의미입니다. 이 경우 jQuery 개체 자체는 기본적으로 대상 개체로 설정됩니다. 이런 방식으로 jQuery 네임스페이스에 새로운 기능을 추가할 수 있습니다. 이는 jQuery에 새로운 기능을 추가하려는 플러그인 개발자에게 유용합니다.

대상 객체(첫 번째 매개변수)가 수정되고 $.extend()를 통해 반환된다는 점을 기억하세요. 그러나 원본 객체를 유지하려면 빈 객체를 대상 객체로 전달하면 됩니다.

var object = $.extend({}, object1, object2);

기본적으로 $.extend()를 통한 병합 작업은 재귀적이지 않습니다. 첫 번째 개체의 속성 자체가 개체 또는 배열인 경우 두 번째 개체의 동일한 키로 속성을 완전히 덮어씁니다. 이 값은 병합되지 않습니다. 아래 예에서 바나나의 값을 검토하면 이를 확인할 수 있습니다. 그러나 true가 함수의 첫 번째 인수로 전달되면 객체에 대해 재귀 병합이 수행됩니다.

경고: 첫 번째 인수로 false를 전달하는 것은 지원되지 않습니다.

1. 두 개체를 병합하고 첫 번째 개체를 수정합니다.

var object1 = {
 apple: 0,
 banana: { weight: 52, price: 100 },
 cherry: 97
};
var object2 = {
 banana: { price: 200 },
 durian: 100
};
 
// Merge object2 into object1
$.extend( object1, object2 );
 
// Assuming JSON.stringify - not available in IE<8
console.log( JSON.stringify( object1 ) );
//{"apple":0,"banana":{"price":200},"cherry":97,"durian":100}

2. 두 개체를 재귀적으로 병합하고 첫 번째 개체를 수정합니다.

var object1 = {
 apple: 0,
 banana: { weight: 52, price: 100 },
 cherry: 97
};
var object2 = {
 banana: { price: 200 },
 durian: 100
};
 
// Merge object2 into object1, recursively
$.extend( true, object1, object2 );
 
// Assuming JSON.stringify - not available in IE<8
console.log( JSON.stringify( object1 ) );
//{"apple":0,"banana":{"weight":52,"price":200},"cherry":97,"durian":100}

3. 기본 개체를 수정하지 않고 기본 개체와 옵션 개체를 병합합니다. 이는 일반적으로 사용되는 플러그인 개발 모델입니다.

var defaults = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
 
// Merge defaults and options, without modifying defaults
var settings = $.extend( {}, defaults, options );
 
 
console.log(JSON.stringify( defaults ));
console.log(JSON.stringify( options ));
console.log(JSON.stringify( settings ));
//defaults -- {"validate":false,"limit":5,"name":"foo"}
//options -- {"validate":true,"name":"bar"}
//settings -- {"validate":true,"limit":5,"name":"bar"}

위의 예에서 볼 수 있듯이 "==" 또는 "==="를 사용하면 false가 반환됩니다. 그 주된 이유는 기본형인 string과 number는 값으로 비교하고, 객체(Date, Array)와 일반 객체는 포인터가 가리키는 메모리의 주소로 비교하기 때문이다. 다음 예를 보십시오.

위의 예는 obj1과 ob3의 포인터가 메모리의 동일한 주소를 가리키기 때문에 true를 반환합니다. 객체 지향 언어(Java/C++)의 값 전달 및 참조 전달 개념과 유사합니다. 왜냐면 두 객체가 동일한지 판단하려면 두 객체의 속성이 동일한지, 아니면 해당 속성에 해당하는 값이 동일한지, 아니면 무엇인지를 명확하게 판단해야 하기 때문입니다. ?
var obj1 = {
  name: "Benjamin",
  sex : "male"
}
 
var obj2 = {
  name: "Benjamin",
  sex : "male"
}
 
//Outputs: false
console.log(obj1 == obj2);
 
//Outputs: false
console.log(obj1 === obj2);

위 내용이 이 글의 전체 내용입니다. 모든 분들의 학습에 도움이 되기를 바랍니다. 또한 PHP 중국어 웹사이트를 구독하시기 바랍니다.
var obj1 = {
  name: "Benjamin",
  sex : "male"
};
 
var obj2 = {
  name: "Benjamin",
  sex : "male"
};
 
var obj3 = obj1;
 
//Outputs: true
console.log(obj1 == obj3);
 
//Outputs: true
console.log(obj1 === obj3);
 
//Outputs: false
console.log(obj2 == obj3);
 
//Outputs: false
console.log(obj2 === obj3);

js 객체의 얕은 복사와 깊은 복사에 대한 자세한 설명은 PHP 중국어 홈페이지를 참고해주세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.