質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

3回答

563閲覧

javascriptのassignメソッドの使い方が分かりません

tanakashouzoux

総合スコア52

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2020/06/08 05:53

編集2020/06/08 05:54

https://jsprimer.net/basic/object/

上記サイトで下記の様なコードが書かれ、説明に
「注意点として、Object.assignメソッドはsourcesオブジェクトのプロパティを浅くコピー(shallow copy)する点です。 shallow copyとは、sourcesオブジェクトの直下にあるプロパティだけをコピーするということです。 そのプロパティの値がオブジェクトである場合に、ネストした先のオブジェクトまでも複製するわけではありません。」
と書かれています。

「sourcesオブジェクトの直下にあるプロパティだけをコピーするということです。 そのプロパティの値がオブジェクトである場合に、ネストした先のオブジェクトまでも複製するわけではありません。」
との箇所から私は今回の場合
「shallowClone(obj)」
には
「obj={level:1,}」
だけが代入されると思ったのですが、これは間違えているのでしょうか?

間違えている場合「cloneObj.nest」「obj.nest」には何が入っているのでしょうか?

なぜ「console.log(cloneObj.nest === obj.nest); 」は「true」となるのでしょうか?

javascript

1const shallowClone = (obj) => { 2 return Object.assign({}, obj); 3}; 4const obj = { 5 level: 1, 6 nest: { 7 level: 2 8 }, 9}; 10const cloneObj = shallowClone(obj); 11// `nest`オブジェクトは複製されていない 12console.log(cloneObj.nest === obj.nest); // => true

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tanakashouzoux

2020/06/08 21:47

think49さん いつもご指導ありがとうございますm(__)m はい! ググらせて頂いておりました!! shallow copyとdeep copyの違いもググって上記リンクで勉強させて頂いておりました! 「オブジェクトまでも複製するわけではありません。」という表現がどうも理解出来なくて悩んでいたのですが、これは「参照しているだけで新しいコピーを作っているわけではない」という認識でよろしいのでしょうか?
guest

回答3

0

ベストアンサー

assignメソッドの使い方

オブジェクトの複製には shallow copy と deep copy の2種類がありますので、この2種類を理解して使いどころを意識します。

shallow copy は プリミティブじゃない値(オブジェクト)は参照が渡されます。

javascript

1const obj = { 2 level: 1, 3 nest: { 4 level: 2 5 }, 6}; 7// cloneObj.nest は obj.nest の参照なので、いずれかを変更すると他方も変更する 8const cloneObj = Object.assign({}, obj); 9 10cloneObj.nest.level++; 11console.log( JSON.stringify(obj) ); // {"level":1,"nest":{"level":3}} 12console.log( JSON.stringify(cloneObj2) ); // {"level":1,"nest":{"level":3}}

deep copy は参照を断ち切るために、値がobject の場合、(再帰処理で)深堀りし、プリミティブを複製します。
(obj.nest.level はそのままに、cloneObj.nest.level だけを変できるようになる)

javascript

1const obj = { 2 level: 1, 3 nest: { 4 level: 2 5 }, 6}; 7// オブジェクトリテラルは ``JSON.parse(JSON.stringify(boj))`` で deep copy できる。 8const cloneObj = JSON.parse(JSON.stringify(obj)); 9 10cloneObj.nest.level++; 11console.log( JSON.stringify(obj) ); // {"level":1,"nest":{"level":2}} 12console.log( JSON.stringify(cloneObj) ); // {"level":1,"nest":{"level":3}}

jQuery の $.extend() が deep copy にも対応したユーティリティ関数として有名です。

投稿2020/06/08 07:12

AkitoshiManabe

総合スコア5432

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tanakashouzoux

2020/06/08 21:50

AkitoshiManabeさん わざわざご丁寧にコードまで記述頂きありがとうございますm(__)m 「shallow copy は プリミティブじゃない値(オブジェクト)は参照が渡される」んですね♪ こう説明して頂けたお陰で大変理解が進みました!!! ありがとうございます!!! 「ネストした先のオブジェクトまでも複製するわけではありません」というのは「ネストした先のオブジェクトはコピーではなく参照をします」という認識で合ってますでしょうか?
guest

0

===によるオブジェクトの比較は、同じオブジェクトの実体を指す場合にtrueとなります。
逆に言えば、trueとなった場合は、同じオブジェクトの実体を指しているので、オブジェクトは増えていない、つまり複製されていないということです。

js

1const nest = { 2 level: 2 3}; 4 5const obj = { 6 level: 1, 7 nest: nest, 8}; 9 10const cloneObj = shallowClone(obj); 11 12console.log(cloneObj === obj); // => false なので違うオブジェクト = 複製されている 13console.log(cloneObj.nest === nest); // => true なので同じオブジェクト = 複製されていない 14console.log(obj.nest === nest); // => true なので同じオブジェクト = 複製されていない

投稿2020/06/08 06:56

Lhankor_Mhy

総合スコア36115

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tanakashouzoux

2020/06/08 21:51

Lhankor_Mhyさん ご丁寧に、しかもコードまでありがとうございますm(__)m 聞ける人が身近にいないので本当に助かります(´;ω;`)ウゥゥ
guest

0

単純に、引数1に引数2のオブジェクトの各要素を上書きしていくという理解でよくないですか?

javascript

1var hoge={a:1,b:2}; 2var fuga={a:100,c:300}; 3console.log(Object.assign(hoge,fuga)); //{a:100,b:2,c:300}

投稿2020/06/08 06:10

yambejp

総合スコア114843

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tanakashouzoux

2020/06/08 06:15

yambejpさん わざわざ回答いただきありがとうございますm(__)m yambejpさんのコードだと理解可能なのですが、私が載せたコードだと「ネストした先のオブジェクトまでは複製しません」と書いてあるのに、それだと矛盾する気がするんですよね・・・
yambejp

2020/06/08 06:23 編集

var hoge={a:1,b:2,nest: {d: 4,e:5 }}; var fuga={a: 100,c:300,nest: {d: 400,f:600 }}; console.log(Object.assign(hoge,fuga)); //{a:100,b:2,c:300,nest{d:400,f:600}} 同じnest要素はそのオブジェクトとして上書きされるということで どうでしょう? abcと同等の上書きならnestは{d:400,e:5,f:600}になりそうな 気もするところですが まるっとnestが上書きされているという感覚
tanakashouzoux

2020/06/08 06:42

yambejpさん 何度も本当にありがとうございますm(__)m ご記述頂いたコードは完全に理解出来ていると思います! 上記サイトの「ネストした先のオブジェクトまでは複製しません」というのはどういう意味になるのでしょうか? 「ネストした先のオブジェクトまでは複製しません」=「上書きはするよ」ということなのでしょうか?
yambejp

2020/06/08 06:49

その直後の段落で「逆にプロパティの値までも再帰的に複製してコピーすることを、深いコピー(deep copy)と呼びます。」とあるので 再帰処理されないよ・・・という意図の文書だと思います
yambejp

2020/06/08 07:06 編集

const shallowClone = (obj) => { return Object.assign({}, obj); }; const obj = { level: 1, nest:{level:2}, }; const cloneObj = shallowClone(obj); cloneObj.level=100; cloneObj.nest.level=200; console.log(obj.level); //1 console.log(obj.nest.level); //200 ※イメージ的には参照渡しのような挙動ですね(jsの基本動作)
tanakashouzoux

2020/06/08 21:53

yamabejpさん 何度も何度もご丁寧にありがとうございますm(__)m 参照渡しの様な挙動となるのですね♪ お陰様で理解が深まりました!! ありがとうございます!!!!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問