js 얕 은 복사, 깊 은 복사

3666 단어
머리말
본 고 는 주로 얕 은 복사 가 무엇 인지, 깊 은 복사 가 무엇 인지, 깊 은 복사 와 얕 은 복사 의 차이 점, 그리고 깊 은 복사 와 얕 은 복사 가 어떻게 진행 되 는 지 간단하게 설명 한다.
얕 은 복사 와 깊 은 복사 의 차 이 는 주로 메모리 에 있 는 저장 유형 이 다 르 거나 전송 값 과 전송 주소 의 차이 이다.
첫 번 째 단 계 는 자바 script 의 7 내 장 된 유형 을 알 아 보 는 것 입 니 다. 기본 데이터 형식: 스 택 메모리 에 저 장 된 간단 한 데이터 세그먼트, 데이터 크기 가 확정 되 고 메모리 공간 크기 가 분 배 될 수 있 습 니 다.
  • 빈 값 (null)
  • 정의 되 지 않 음 (undefined)
  • 불 값 (boolean)
  • 숫자 (number)
  • 문자열 (string) 6. (symbol, ES6 추가)
  • 참조 형식: 메모리 에 저 장 된 대상 입 니 다. 변 수 는 실제 스 택 메모리 에 저 장 된 지침 입 니 다. 이 지침 은 메모리 에 저 장 된 주 소 를 가리 키 고 있 습 니 다. 공간 마다 크기 가 다 르 므 로 상황 에 따라 특정한 분 배 를 해 야 합 니 다.
  • 대상 (object)
  • 스 택 (stack) 과 더미 (hep)
    stack 은 자동 으로 분 배 된 메모리 공간 입 니 다. 시스템 에서 자동 으로 방출 되 며, 힙 은 동적 으로 분 배 된 메모리 입 니 다. 크기 가 일정 하지 않 아 도 자동 으로 방출 되 지 않 습 니 다. 기본 형식 은 스 택 에 저 장 됩 니 다. 인용 형식 은 더미 에 저 장 됩 니 다. 인용 형식 (예 를 들 어 대상, 배열, 함수 등) 에 접근 해 야 할 때.값 을 얻 을 때, 먼저 창고 에서 이 대상 의 주소 지침 을 얻 은 다음, 메모리 에서 필요 한 데 이 터 를 얻는다.
    예시
          var a = [1,2,3,4,5];
          var b = a;
          var c = a[0];
          alert(b);//1,2,3,4,5
          alert(c);//1
          //            
          b[4] = 6;
          c = 7;
          alert(a[4]);//6
         alert(a[0]);//1
    

    위 에서 알 수 있 듯 이 내 가 b 의 데 이 터 를 바 꿀 때 a 의 데이터 도 변화 가 생 겼 다. 그러나 내 가 c 의 데이터 값 을 바 꿀 때 a 는 변 하지 않 았 다. 이것 이 바로 전송 값 과 전송 주소 의 차이 이다. a 는 배열 이 고 인용 유형 이기 때문에 b 에 게 부 여 된 것 은 스 택 의 주소 (다른 이름 의 '포인터' 를 새로 만 든 것 과 같다) 이다.메모리 의 대상 이 아 닙 니 다. c 는 a 더미 메모리 에서 가 져 온 데이터 값 일 뿐 스 택 에 저 장 됩 니 다. 따라서 b 가 수정 할 때 주소 에 따라 a 더미 로 돌아 가 수정 합 니 다. c 는 스 택 에서 직접 수정 하고 a 더미 메모리 에 가리 킬 수 없습니다.
    삼천 복사
    앞에서 언급 한 바 와 같이 하나의 대상 이나 그룹 을 정의 할 때 변 수 는 하나의 주소 에 만 저 장 됩 니 다. 대상 을 복사 할 때 속성 이 대상 이나 그룹 일 경우 이 때 우리 가 전달 하 는 것 은 하나의 주소 일 뿐 입 니 다. 따라서 하위 대상 은 이 속성 을 방문 할 때 주소 에 따라 부모 대상 이 가리 키 는 메모리 로 거 슬러 올 라 갑 니 다. 즉, '부자 대상 이 관련 되 었 습 니 다' 입 니 다.둘 의 속성 값 은 같은 메모리 공간 을 가리킨다.
        var a = {
              key1:"11111"
          }
          function Copy(p) {
             var c = {};
              for (var i in p) { 
                c[i] = p[i];
             }
             return c;
       }
          a.key2 = ['  ','  '];
          var b = Copy(a);
       b.key3 = '33333';  
          alert(b.key1);     //1111111
         alert(b.key3);    //33333
         alert(a.key3);    //undefined
    

    a 대상 중 key 1 속성 은 문자열 이 고, key 2 속성 은 배열 입 니 다. a 는 b 로 복사 되 며, 12 속성 은 모두 순조롭게 복사 되 었 습 니 다. b 대상 에 게 문자열 형식의 속성 key 3 를 추가 할 때 b 는 정상적으로 수정 할 수 있 으 며, a 에 서 는 정의 가 없습니다. 하위 대상 의 key 3 (기본 형식) 을 설명 합 니 다.부모 대상 에 연결 되 어 있 지 않 기 때문에 undefined 입 니 다. 단, 수 정 된 속성 이 대상 이나 그룹 으로 바 뀌 면 부자 대상 간 에 연결 이 됩 니 다. 상기 팝 업 결 과 를 통 해 알 수 있 듯 이 저 는 b 대상 을 수정 합 니 다. a, b 의 key 2 속성 값 (배열)모두 변경 되 었 습 니 다. 키 1 의 값 은 기본 형식 이기 때문에 복사 할 때 이 데이터 세그먼트 를 전달 합 니 다. 그러나 키 2 의 값 은 메모리 의 대상 이기 때문에 키 2 는 복사 할 때 키 2 대상 을 가리 키 는 주 소 를 전달 합 니 다. 몇 개의 키 2 를 복사 하 더 라 도 그 값 은 항상 부모 대상 을 가리 키 는 키 2 대상 의 메모리 공간 입 니 다.
    딥 카피
    아마도 이상 은 우리 가 실제 인 코딩 에서 원 하 는 결과 가 아 닐 것 입 니 다. 우 리 는 부자 대상 간 에 관련 이 있 기 를 원 하지 않 습 니 다. 이 럴 때 깊 은 복사 본 을 사용 할 수 있 습 니 다. 속성 값 유형 이 배열 이나 이미지 일 때 주소 만 전달 되 는 이상, 우 리 는 재 귀적 으로 이 문 제 를 해결 하고 부모 대상 에 속 하 는 모든 속성 유형 을 하위 대상 에 게 옮 겨 다 니 며 부여 하면 됩 니 다. 테스트 코드다음 과 같다.
    function Copy(p, c) {
            var c = c || {};
            for (var i in p) {
              if (typeof p[i] === 'object') {
                 c[i] = (p[i].constructor === Array) ? [] : {};
                 Copy(p[i], c[i]);
              } else {
                 c[i] = p[i];
              }
            }
            return c;
      }    
        a.key2 = ['  ','  '];
        var b={};
        b = Copy(a,b);        
        b.key2.push("  ");
        alert(b.key2);    //  ,  ,  
        alert(a.key2);    //  ,  
    

    좋은 웹페이지 즐겨찾기