객체 병합 기능 구현에 대한 자세한 설명

小云云
풀어 주다: 2018-01-26 11:54:09
원래의
1150명이 탐색했습니다.

이 글에서는 주로 객체 병합 기능을 기반으로 한 구현 예시를 소개합니다. 편집자님이 꽤 좋다고 생각하셔서 지금 공유하고 모두에게 참고용으로 드리고자 합니다. 편집자를 따라가서 모두에게 도움이 되기를 바랍니다.

jQuery의 Foreword

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

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

이전 블로그 게시물에서는 객체와 배열의 깊은 복사와 얕은 복사에 대해 구체적으로 소개했습니다. 이해가 안 되신다면 여기를 읽어보세요. 먼저 구현을 살펴보고 설명하겠습니다

function extend() { //extend 浅拷贝实现
  var name,options,copy,
   length = arguments.length,
   i = 1,
   target = arguments[0] || {}; //取目标对象
  
 if(['object','function'].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,'a']
 },
 test2 = {
  b : {
  c : 4,
  d : 5,
  f : 6
  },
  e : [1,'a'],
  g : 7
 }

 var test = extend({},test1,test2);
 console.log(test.b.d); //5

 test2.b.d = 'x'; //修改test2
 console.log(test.b.d); // 'x' test随之修改
로그인 후 복사

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

1. 기본적으로 첫 번째 매개변수가 객체 데이터 유형이 아닌 경우 값은 다음과 같습니다. 빈 객체에 할당됨

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

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 == 'boolean'){
  deep = arguments[0];
  target = arguments[i] || {}; //目标对象顺延
  i++;
  }

  //如果target不是对象数据类型的话 target赋值为 {}
  if(['object','function'].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 == 'object')){ // 类型判断

    src = Object.prototype.toString.call(copy) == '[object Array]' ? [] : {}; //区分数组和‘对象'
    target[name] = extend(deep,src,copy);
   }else {

    if (copy !== undefined) {

    target[name] = copy;
    }
   }
   }
  }
  }

  return target
 }
로그인 후 복사

1. 매개변수 판단, 첫 번째 매개변수가 Boolean 유형인 경우 Deep Copy 여부를 제어하는 ​​매개변수 deep으로 가져옵니다. deep의 기본값은 동시에 false이며, 대상 요소는 두 번째 매개변수입니다

2. 값이 객체 유형이면 확장 함수를 재귀적으로 호출하고, 그렇지 않으면 값을 직접 할당하십시오

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

Conclusion

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

관련 권장 사항:

객체 병합 기능 구현 방법

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

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