ホームページ  >  記事  >  ウェブフロントエンド  >  オブジェクト結合機能の実装について詳しく解説

オブジェクト結合機能の実装について詳しく解説

小云云
小云云オリジナル
2018-01-26 11:54:091064ブラウズ

この記事では主にオブジェクト結合機能に基づいた実装例を紹介します。編集者はこれが非常に良いものだと思ったので、皆さんの参考として今から共有します。編集者をフォローして見てみましょう。皆さんのお役に立てれば幸いです。

はじめに

$.extend() は、主にパラメーター (オブジェクト) をマージするために使用される、頻繁に使用されるツール関数です。ここでは、具体的な使用方法については説明しません。マージ プロセス中にディープ コピーを使用するかどうかを制御できます。 ES2015 の新しい Object.assign() メソッドでもオブジェクトのマージを実現できますが、この記事ではオブジェクトをマージするための jQuery の extend メソッドのソース コードを参照しています。つまり、複数のオブジェクトの属性がターゲット オブジェクトにコピーされます。同じ属性が存在する場合、後のオブジェクトが前のオブジェクトを上書きします。

浅いコピーによるオブジェクトのマージの実現

以前のブログ投稿では、オブジェクトと配列の深いコピーと浅いコピーについて詳しく紹介しました。理解できない場合は、こちらをお読みください。最初に実装を見てから説明しましょう

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. マージ結果としてターゲットオブジェクトを返します

2 番目のステップでは、ソースオブジェクトの属性値はすべて '=' を使用して行われます。 object 属性、copy あくまで参考値であり、浅いコピー方法です。 テスト結果から、test と test2 の b 属性の属性値は同じオブジェクトを使用しており、相互に影響を与えることがわかります。 。これを理解すると、マージ中にディープ コピーを実装する方法についてもアイデアが得られるはずです。

ディープ コピーによるオブジェクトのマージ

を実装するには、ソース オブジェクトの属性値をコピーするときに値の型を決定する必要があります。それがオブジェクト データ型の場合は、extend 関数を再帰的に呼び出します。次に、オブジェクトのマージのディープ コピー方法を練習します。実装は次のとおりです:

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. パラメーターの判断、最初のパラメーターがブール型の場合、ディープ コピーするかどうかを制御するパラメーター deep として解釈されます。 deep のデフォルトは false であり、同時にターゲット要素は 2 番目のパラメータです

2。deep が true の場合は deep パラメータと属性値の型を決定する必要があります。 value がオブジェクト型の場合は、extend 関数を再帰的に呼び出します。それ以外の場合は、値を直接割り当てます

3. ターゲット オブジェクトのプロパティに異なる初期値を割り当てるには、配列と「オブジェクト」を区別する必要があります。全て{}の場合、対象要素にコピーされた配列型の属性値は、{'0':xx, '1': xx...}になります

結論

常に$.extendを直接使用してください() 、使いやすいですが、実装についてはよくわかりません。* 実装は厳密ではないかもしれませんが、利益はかなり良いと思います。

関連する推奨事項:

オブジェクト結合機能の実装方法

以上がオブジェクト結合機能の実装について詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。