JavaScript 얕 은 층 클론 과 깊이 클론 예제 상세 설명

1 지식 포인트
4.567917.얕 은 복 제 는 스 택 메모리 의 인용 을 한 부 복사 하고 새로운 변 수 를 부여 하 는 것 이다.본질 적 으로 두 개의 가리 키 는 메모리 의 같은 주소 이 고 내용 도 같 으 며 그 중의 하 나 는 변화 하고 다른 내용 도 변화 할 것 이다.
4.567917.심 복 제 는 새로운 빈 대상 을 만 들 고 메모리 하 나 를 만 든 다음 에 원래 대상 의 데 이 터 를 모두 복사 하여 두 대상 간 의 관 계 를 완전히 차단 하 는 것 이다4.567917.차이 점:얕 은 복제 와 깊 은 복제 의 가장 큰 차 이 는 바로 인용 치 에 대한 처리 이다.즉,얕 은 복제 후에 네가 고치 면 나 도 고치 고,깊 은 복제 후에 네가 고치 면 나 는 고치 지 않 는 다.(PS:원시 값 의 처리 와 같다)
  • 원시 값(스 택 데이터 스 택):Number,Boolean(false/true),String,undefined,null
  • 인용 값(데이터 힙 쌓 기):Array,Object,function/날짜,RegExp
  • 2.얕 은 층 클론
    얕 은 층 복제 에서 원시 값 의 복 제 는 문제 가 없다.단지 값 의 복사 일 뿐,네가 나 를 고 치 는 문제 가 발생 하지 않 을 것 이다.그러나 인용 값 의 복 제 는 나 도 고 치 는 문제 가 발생 할 것 이다.왜냐하면 얕 은 층 의 복 제 는 주소,즉 같은 공간 을 가리 키 기 때문이다.
    2.1 얕 은 클론 함수
    
    function clone(origin, target) {
      var target = target || {}; 
      //  ,            。          ,             
      for (var prop in origin) {
        target[prop] = origin[prop];
      }
      return target;
    }
    
    2.2 인 스 턴 스 활용
    
    function clone(origin, target) {
      var target = target || {}; 
      for (var prop in origin) {
        target[prop] = origin[prop];
      }
      return target;
    }
    
    var obj = {
      name: 'abc',
      age: '18',
      sex: 'male',
      card: ['a', 'b', 'c'],
      book: {
        name: 'ccc',
        sbook: {
          name: 'aaa'
        }
      }
    };
    var newobj = {};
    
    clone(obj, newobj);
    
    실행 코드 는 다음 과 같 습 니 다:

    3 깊이 클론
    심도 있 는 복 제 를 한 후에 인용 값 에 대한 복 제 는 원시 값 과 마찬가지 로 바 뀌 지 않 습 니 다.깊이 있 는 복제 에 서 는 같은 것 이지 만 다른 공간 을 가리 키 기 때 문 입 니 다.즉,깊이 복제 후 값 은 각자 독립 되 어 서로 영향 을 주지 않 는 다.
    3.1 딥 클론 절차 분석
    심도 있 는 복제 대상 은 다음 과 같 습 니 다.
    
    var obj = {
      name: 'abc', //    
      age: '18', //    
      sex: 'male',//    
      card: ['a', 'b', 'c'], //    
      book: { //    
        name: 'ccc', //    
        sbook: { //    
          name: 'aaa'//    
        }
      }
    };
    
    var obj1 = {};
    
    (1)우선 복제 할 대상 을 옮 겨 다 녀 야 한다.
    방법:for(var prop in origin){..}
    
    for (var prop in origin) {
    	・・・
    }
    
    (2)원시 값 인지 아 닌 지 순서대로 판단 한다.
    방법:type:of(),즉 원시 값 이 라면 직접 복사 합 니 다.인용 값(type:of(..)을 되 돌려 주 는 값 이 object)이면 재 귀 작업 을 합 니 다.주의해 야 할 것 은 type:of(null)='object'이기 때문에 이 상황 을 제외 해 야 합 니 다.
    
    if (origin[prop] !== "null" && typeof(origin[prop]) == 'object') {
    	・・・
    	//   
    } else {
      target[prop] = origin[prop];
    }
    
    (3)배열 인지 대상 인지 판단
    방법:toString(추천),constructor,instanceof(후 두 개 는 부자 역 과 관련 된 작은 문제 입 니 다.큰 문 제 는 아 닐 수 있 지만)
    
    var toStr = Object.prototype.toString,
      arrStr = "[object Array]";
    if (toStr.call(origin[prop]) == arrStr) {
    	・・・ //   
    } else {
    	・・・ //   
    }
    
    (4)해당 하 는 배열 이나 대상 을 구축한다.
    방법:새로운 동명 빈 배열/대상 을 만 들 고 원본 대상 의 배열 이나 대상 을 새로운 원본 대상 으로 삼 아 그 중의 데 이 터 를 대상 의 동명 빈 배열/대상 에 다시 복사 합 니 다.즉,배열 이나 대상 의 데 이 터 를 재 귀적 으로 복사 하고 제(1)단 계 를 재 귀적 으로 실행 하 는 것 이다.재 귀 완료 후 다음 데이터 복 제 를 순서대로 진행 합 니 다.
    
    var toStr = Object.prototype.toString,
      arrStr = "[object Array]";
    if (toStr.call(origin[prop]) == arrStr) {
    	target[prop] = [];
    } else {
    	target[prop] = {};
    }
    
    
    newobj = {
      name: 'abc',
      age: '18',
      sex: 'male',
      card: [] 
      //            ,  obj card          ,     obj1 card  
      //                   ,     (1) 
      //      card    ,           book・・・
    }
    
    3.2 딥 클론 함수
    
    function deepClone(origin, target) {
      var target = target || {},
        toStr = Object.prototype.toString,
        arrStr = "[object Array]";
      for (var prop in origin) {
        if (origin.hasOwnProperty(prop)) {
          if (origin[prop] !== "null" && typeof(origin[prop]) == 'object') {
            if (toStr.call(origin[prop]) == arrStr) {
              target[prop] = [];
            } else {
              target[prop] = {};
            }
            deepClone(origin[prop], target[prop]);
    
          } else {
            target[prop] = origin[prop];
          }
        }
      }
      return target;
    }
    
    세 개의 연산 자 를 사용 하여 간소화 한 코드 는 다음 과 같다.
    
    //           
    function deepClone(origin, target) {
      var target = (target || {}),
        toStr = Object.prototype.toString,
        arrStr = "[object Array]";
      for (var prop in origin) {
        if (origin.hasOwnProperty(prop)) {
          if (origin[prop] !== "null" && typeof (origin[prop]) == 'object') {
            target[prop] = toStr.call(origin[prop]) == arrStr ? [] : {};
            deepClone(origin[prop], target[prop]);
          } else {
            target[prop] = origin[prop];
          }
        }
      }
      return target;
    }
    
    3.3 인 스 턴 스 활용
    
    //           
    function deepClone(origin, target) {
      var target = (target || {}),
        toStr = Object.prototype.toString,
        arrStr = "[object Array]";
      for (var prop in origin) {
        if (origin.hasOwnProperty(prop)) {
          if (origin[prop] !== "null" && typeof (origin[prop]) == 'object') {
            target[prop] = toStr.call(origin[prop]) == arrStr ? [] : {};
            deepClone(origin[prop], target[prop]);
          } else {
            target[prop] = origin[prop];
          }
        }
      }
      return target;
    }
    
    실행 코드 는 다음 과 같 습 니 다:

    3.4 hasOwnProperty
    hasOwnProperty()방법 은 불 값 을 되 돌려 줍 니 다.대상 자체 속성 에 지정 한 속성 이 있 는 지 여부(즉,지정 한 키 가 있 는 지 여부)를 표시 합 니 다.
    문법:obj.hasOwnProperty(prop)
    인자:검사 할 속성의 문자열 형식 으로 표시 할 이름 이나 Symbol.
    반환 값:대상 이 지정 한 속성 을 가지 고 있 는 지 판단 하 는 불 값 입 니 다.
    설명:Object 를 물 려 받 은 모든 대상 은 hasOwnProperty 방법 으로 물 려 받 습 니 다.이 방법 은 한 대상 이 특정한 자신의 속성 을 가지 고 있 는 지 검사 하 는 데 사용 할 수 있다.in 연산 자 와 달리 이 방법 은 원형 체인 에서 계 승 된 속성 을 무시 합 니 다.
    사용법:
    a.hasOwnProperty 방법 으로 속성 존재 여 부 를 판단 합 니 다.
    b.자신의 속성 과 계승 속성 을 구별
    c.대상 의 모든 속성 을 옮 겨 다 니 기
    d.hasOwnProperty 를 속성 명 으로 사용 합 니 다.
    구체 적 인 지식 포 인 트 는 참고 하 세 요.
    대상 에 원형 속성 이 작성 되 어 있 지만,옮 겨 다 닐 때 보이 지 않 으 려 면 대상 이름.hasOwnProperty(속성 명)를 사용 하여 자신의 속성 여 부 를 판단 할 수 있 습 니 다.자신의 것 이 라면 값 을 true 로 되 돌려 주 고,자신의 원형 속성 이 아니라면 값 을 false 로 되 돌려 줍 니 다.실례 는 다음 과 같다.
    
    var obj = {
    	name: 'ABC',
    	age: '18',
    	sex: 'male',
    	__proto__: {
    		heart: 'happy'
    	}
    }
    for (var prop in obj) {
    	//     ,         ,            
    	if (obj.hasOwnProperty(prop)) {
    		console.log(obj[prop]);// ABC 18 male
    	}
    }
    
    개인 노트,여러분 의 교류 와 토론 을 환영 합 니 다!
    총결산
    자 바스 크 립 트 의 얕 은 복제 와 깊이 있 는 복제 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.자 바스 크 립 트 의 얕 은 복제 와 깊이 있 는 복제 에 관 한 더 많은 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부탁드립니다!

    좋은 웹페이지 즐겨찾기