オブジェクトのJS直接割り当て、シャローコピーとディープコピー

  Vueのプロジェクトは、最近のビジネスを書いた後、それはエル・テーブル形式に堆積され、各提出後]をクリックし、データフォーム]ダイアログボックスに入れる必要があり、フォームデータは、フォームに複数回提出する必要が、その後されていますまた、プレビュー、他の操作中にテーブルを変更することができるフォームデータの複数を達成するために、提出するためにこのフォームを提出します。コードテーブルコードに各フォームデータは、実質的に、以下:

    オブジェクト= this.ruleFormてみましょう。

    this.tableData.push(オブジェクト)。

  ダイアログがフォームEL-形態で使用される、this.ruleForm VUEは、オブジェクトのインスタンスであり、this.tableData VUEは、配列オブジェクトのインスタンスです。This.ruleFormは直接変数オブジェクトに割り当てられ、その後、再び各this.tableDataに押し込み、それは論理的に見えることは何も間違っているようですが、これは奇跡的な現象が生成されます:あなたは、フォームデータを記入するたびにテーブル内のデータの各行があなたとされるときに記入するフォームが変更されます。

  ここでは直接割り当てのjsオブジェクト、シャローコピーとディープコピーを含む、対象になる問題があります。

直接割り当て

  それらは実際には同じオブジェクトであるように、オブジェクトは、オブジェクトのターゲットアドレスを指し示す目標アドレスに対するB Bと同等に割り当てられます。このプロジェクトはVueのであるので、問題は直接割り当てに登場し、応答のVueのタイプは、彼らの本質を知っているあなたはより直感的になります。図1の例に直接割り当て、人物オブジェクトは、2つのプロパティ、1名、1つのオブジェクトのプロパティageAndSexがあり、オブジェクトのプロパティを取得する必要がありますなぜ、これが深いと浅いコピーコピーバックの問題を伴うだろう、これはそれらの和であります違い。メモリアドレスが監視することは困難であるが、私たちは、厳密な等価演算子で同じアドレスに両方のポイントを検出することができますので、「===。」

 双方は、図1のオブジェクトである場合、オペレータは、同じメモリアドレスを指すかどうかをチェックするために厳密に等しくなります。

  例の一例は、図2に示すように。name属性personCopy剛への代入の初めに、我々は、人も変わりました。17歳のプロパティの割り当てpersonCopyにAgeAndSexオブジェクトのプロパティ、人も変わります。すなわち:直接割り当て、また、譲渡後に非対象オブジェクトbのプロパティを変更しますで、元のオブジェクトに影響を与える非オブジェクトのプロパティ、割り当て後のオブジェクトのB変更オブジェクト属性を、またなり、元のオブジェクトAに影響を与えるオブジェクトのプロパティを

図2の直接割り当て

シャローコピー

  シャローコピーは唯一の割り当て非オブジェクトのプロパティオブジェクトは、同じアドレスを指していますでしょう。浅いコピーES6方法Object.assign(ターゲット、...源)があります。図に示すように、例えば、直接オブジェクトへの割り当てに先立っ。

図3浅いコピー、オブジェクトがコピーされたオブジェクトの割り当ては、同一のアドレスを指していません

  割り当ての非対象オブジェクトbのプロパティが変更しないで元のオブジェクトに影響を与える非オブジェクトのプロパティ、割り当て後のオブジェクトのB変更オブジェクト属性が、それがされます、元のオブジェクトに影響を与えているオブジェクトの属性図に示すように、。

図の浅いコピー4

  ES6拡張演算子「...」浅いコピーがオブジェクトの前または中に、例えば、この形式で書くことができ、達成することができるもあります。var personCopy = {...}人は、図に示すように。

図5拡張オペレータ実装浅いコピー(割当「シャオガン」とアウトに付着しないような、以前の操作の結果と同じです)

   あなたのプロジェクトがES6をサポートしていますが、浅いコピーを達成したくない場合は、サポートES6のレベルを考えると、あなたはまた、連結方法JSネイティブを試すことができます。しかし、唯一の連結動作アレイので、この形式で記述され、オブジェクトのアレイパッケージとして一人称する必要があります。

    var person=[{name:"小明",ageAndSex:{age:16,sex:"男"}}];

    var personCopy=[].concat(person);

如图6所示,到时想得到person对象的时候var personCopyObjet=pesronCopy[0]即可。

 图6 concat方法实现浅拷贝

深拷贝

  深拷贝会另外拷贝一份一个一模一样的对象,但是不同的是会从堆内存中开辟一个新的区域存放新对象,新对象跟原对象不再共享内存,修改赋值后的对象b不会改到原对象a。即深拷贝,修改赋值后的对象b的非对象属性,不会影响原对象a的非对象属性;修改赋值后的对象b的对象属性,也不会影响原对象a的对象属性。而且,二者不指向同一个对象。

  很明显,深拷贝比较符合我这次的业务需求。深拷贝,比较笨一点的办法就是将自己需要的数据自己封装起来。

      let object={
                           repayment:this.ruleForm.repayment,
                           interestType:this.ruleForm.interestType,
                           productDeadline:this.ruleForm.productDeadline,
                           circumstancesOfDetention:this.ruleForm.circumstancesOfDetention,
                           }
                      this.tableData.push(object);

  但是,这样明显会使代码很臃肿,而且,这还是在需要的数据只有4条的情况下,如果这个object需要封装十几条非对象属性的情况下,明显结构不复杂的情况下,这种代码需要改进。

  有一种非常简单的方法就是序列化成为一个JSON字符串,将对象的内容转换成字符串的形式,再用JSON.parse()反序列化将JSON字符串变成一个新的对象,这样原对象就与复制后的新对象没了必然的关系。以前文提到的personCopy和person为例,写法如下:var personCopy=JSON.parse(JSON.stringify(person));如图7所示。

图7 深拷贝

  但是由于用到了JSON.stringify(),这也会导致一系列的问题,因为要严格遵守JSON序列化规则:原对象中如果含有Date对象,JSON.stringify()会将其变为字符串,之后并不会将其还原为日期对象。或是含有RegExp对象,JSON.stringify()会将其变为空对象,属性中含有NaNInfinity-Infinity,则序列化的结果会变成null,如果属性中有函数,undefined,symbol则经过JSON.stringify()序列化后的JSON字符串中这个键值对会消失,因为不支持。

  所以,这个时候笨的办法也是有好处的,就是面对一些特殊的类型,或是对象属性复杂的情况下,因为自己对程序的需求比较了解,就可以按照自己的需要进行封装。不管黑猫白猫,能抓到老鼠的就是好猫。

おすすめ

転載: www.cnblogs.com/jdWu-d/p/11959800.html