객체 병합 기능 구현 방법

一个新手
풀어 주다: 2017-10-12 10:16:49
원래의
2643명이 탐색했습니다.

Foreword

 $.extend()는 자주 사용되는 도구 함수로, 주로 매개변수(객체)를 병합하는 데 사용됩니다. 구체적인 사용법은 여기에서 자세히 설명하지 않습니다. 병합 과정에서 전체 복사 사용 여부를 제어할 수 있습니다. ES2015의 새로운 Object.sign() 메소드도 객체 병합을 실현할 수 있지만 병합 프로세스에서는 얕은 복사본이 사용됩니다. 이 기사에서는 객체 자체를 병합하는 jQuery의 확장 메소드 소스 코드를 참조합니다. 즉, 여러 객체의 속성을 대상 객체에 복사합니다. 동일한 속성을 가지고 있으면 나중 객체가 이전 객체를 덮어씁니다.

얕은 복사를 통한 객체 병합 달성

 이전 블로그 게시물에서는 객체와 배열의 깊은 복사와 얕은 복사에 대해 구체적으로 소개했습니다. 먼저 구현을 살펴보고 설명하겠습니다


    function extend() {  //extend 浅拷贝实现
      var name,options,copy,
          length = arguments.length,
          i = 1,
          target = arguments[0] || {};  //取目标对象
      
    if([&#39;object&#39;,&#39;function&#39;].indexOf(typeof target) < 0){
        target = {};
      }    

      for(;i<length;i++){

        options = arguments[i]        
        if(options != null){  //排除空参数的情况 extend({},,)

          for(name in options){   //遍历对象 赋值
            copy = options[name];            
            if (copy !== undefined) {
              target[name] = copy;
            }
          }
        }
      }      return target  
    }   //测试数据 
    var test1 = {
      a : 1,
      b : {
        c : 2,
        d : 3
      },
      e : [1,&#39;a&#39;]
    },
    test2 = {
      b : {
        c : 4,
        d : 5,
        f : 6
      },
      e : [1,&#39;a&#39;],
      g : 7
    }    var test = extend({},test1,test2);
    console.log(test.b.d);   //5
    test2.b.d = &#39;x&#39;;  //修改test2
    console.log(test.b.d);  // &#39;x&#39;   test随之修改
로그인 후 복사

아이디어는 다음과 같습니다.

 1. 기본적으로 첫 번째 매개변수가 객체 데이터 유형이 아닌 경우에는 첫 번째 매개변수가 대상 개체로 사용됩니다. 값은 빈 개체에 할당됩니다

 2. 나머지 Parameter(소스 개체)를 탐색하여 원본 개체의 속성을 대상 개체에 복사합니다.

 3. 대상 개체를 병합 결과로 반환

 두 번째 단계에서는 원본 개체의 속성 값을 판단하지 않으며 모든 할당은 '='를 사용하여 이루어지므로 원본 개체의 속성 값이 object 속성, copy 그냥 참조값일 뿐이고, 얕은 복사 방식이다. 테스트 결과를 보면 test 와 test2 의 b 속성 값이 같은 객체를 사용하고 서로 영향을 끼치는 것을 알 수 있다. . 이를 알고 나면 병합 중에 전체 복사를 구현하는 방법에 대한 아이디어가 있어야 합니다.

딥 카피를 통한 객체 병합 달성

 원본 객체 속성 값을 복사할 때 해당 값의 유형을 결정해야 합니다. 객체 데이터 유형인 경우 확장 함수를 재귀적으로 호출합니다. 그러면 객체 병합의 deep copy 방법을 연습할 수 있으며 구현은 다음과 같습니다:


    function extend() {  //extend 深拷贝实现
      var name,options,src,copy,
          deep = false,  //是否深拷贝 默认为false
          length = arguments.length,
          i = 1,
          target = arguments[0] || {};      //如果第一个参数为boolean类型,赋值给deep
      if(typeof target  == &#39;boolean&#39;){
        deep = arguments[0];
        target = arguments[i] || {}; //目标对象顺延
        i++;
      }      //如果target不是对象数据类型的话  target赋值为 {}
      if([&#39;object&#39;,&#39;function&#39;].indexOf(typeof target) < 0){
        target = {};
      }      for(;i<length;i++){

        options = arguments[i];        
        if(options != null){          
        for(name in options){

            copy = options[name];
            src = target[name];            
            if(target === copy){  //避免重复循环
              continue;
            }            if(deep && copy && (typeof copy == &#39;object&#39;)){ // 类型判断
              src = Object.prototype.toString.call(copy) == &#39;[object Array]&#39; ? [] : {};  //区分数组和‘对象’
              target[name] = extend(deep,src,copy);
            }else {              
            if (copy !== undefined) {

                target[name] = copy;
              }
            }
          }
        }
      }      return target
    }
로그인 후 복사

  1. 매개변수 판단, 첫 번째 매개변수가 Boolean 유형인 경우 여부를 제어하는 ​​매개변수 deep으로 간주됩니다. deep copy, deep은 동시에 false로 설정됩니다. 대상 요소는 두 번째 매개변수

  2입니다. 속성 값을 복사할 때 deep이 true이고 속성인 경우 deep 매개 변수의 유형과 속성 값을 결정해야 합니다. 값이 객체형이면 확장 함수를 재귀적으로 호출하고, 아니면 직접 값을 할당하세요

 3. 대상 객체의 속성에 서로 다른 초기값을 할당하려면 배열과 '객체'를 구분해야 합니다. 모두 {}이면 대상 요소에 복사된 배열 유형의 속성 값은 {'0':xx, '1':xx...}

Conclusion

 항상 $.extend를 직접 사용하세요() , 사용하기는 쉽지만 구현에 대해 명확하지 않습니다. I*는 구현이 엄격하지 않을 수 있지만 이득은 꽤 좋다고 생각합니다.

위 내용은 객체 병합 기능 구현 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿