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

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

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

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

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

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

4回答

1404閲覧

オブジェクトの同じプロパティから何度も値を取得する場合について

takuya_am

総合スコア16

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

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

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

1クリップ

投稿2021/01/14 06:41

知りたいこと

APIを叩いて取得したJSONをもとに処理が実装されているコードで、該当のソースコード に記載したようなソースコードを仕事で見かけます。

□ オブジェクトの同じプロパティから何度も値を取得する場合
・変数に格納したほうが良い?
・変数に格納したほうが良い(悪い)場合の理由(速度が速いとか?)
・その他 メリット/デメリット が知りたいです。

該当のソースコード

javascript

1const resultData = { 2 a: { 3 b: { 4 c: { 5 d: "データ" 6 } 7 } 8 } 9} 10 11// ↓こうしたほうがいい? 12// resultHogeHogeData = resultData.a.b.c.d; 13 14if (typeof resultData.a.b.c.d === "string") { 15 if (resultData.a.b.c.d.length === 0) { 16 17 } else if (resultData.a.b.c.d.length === 1) { 18 19 } 20} else if (typeof resultData.a.b.c.d === "boolean") { 21 22} else if (typeof resultData.a.b.c.d === "function") { 23 24} else { 25 26} 27 28// その後の処理でもなんだかんだ使ったり 29 30

自身では
変数に格納せずそのままアクセスして値を取得したほうが、どのプロパティから値を取得しているかがわかりやすい。
(変数に入れると変数名ではオブジェクトのどの階層のプロパティにアクセスしているかまで一見してわからない)
でも、こういうのは変数に格納するっていう先入観があるからなぁ・・・と悩ましい状態です。

素朴な疑問で申し訳ありませんが、どなたかご存じの方がおられましたらご教示頂けますと幸いです。
よろしくお願い致します。

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

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

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

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

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

guest

回答4

0

ベストアンサー

10年前の古いデータですが、、(ハイパフォーマンスJavascipt(オライリー)より)
イメージ説明
リテラルやローカル変数に比べて、オブジェクトメンバへのアクセスは、多少コストがかかる傾向にはあるのは確かですが、まぁ誤差ですね。

resultData変数の定義場所と利用箇所が同じ関数ローカルなら、オブジェクトのネストが深くても、ローカル変数に持ち直す事のパフォーマンス的なメリットはあまりないと思います。

ただ長くなりすぎると、コードが横に伸びて読みにくいので、可読性的な意味で持ち直す事は、個人的にはわりとやります。

ただし、関数外に定義した変数を読む場合、関数スコープを手繰って行くコストがかかる場合があるため、
オブジェクトのネストは関係なく、ローカルに持ち直すことはパフォーマンス的に有利になります。

javascript

1a = 1 2 3function func1() { 4 5 var b = 2 6 var c = 3 7 8 function func2() { 9 var e = 4 10 11 alert(a) 12 } 13}

このfunc2を呼び出す際、利用している変数「a」を探すため、

  1. func2 のローカルスコープ内を探す
  2. func1 のスコープ内を探す
  3. グローバルスコープ内を探す

という形で走査して変数を探すことになるため、ローカルに定義された変数へのアクセスが、最もコストが安い事になります。
なので、例えばグローバルに定義されているdocumentオブジェクト等をループで何度も参照するような場合など、あえてローカルに持ち直したりします。

頻繁につかうスコープ外の変数をローカルに持ち直すのは、パフォーマンス的に有利です。

javascript

1function func1() { 2 3 function func2() { 4 var doc = document; // グローバルなdocumentをローカルに持ち直す。 5 6 for(var i=0; i<100000; i++) { 7 var tmp = doc.getElementById("id_" + i).value; 8 } 9 } 10}

※ブラウザの実装によって最適化されていたりもします。なので効果は必要に応じて対象ブラウザで計測すべきことなので、あくまで一般論としてとらえて下さい。

示されているソースの例の場合、オブジェクトのネストを気にするよりも、
if文を何度も書かずにswitch文を使えば、キレイになる気がします。

javascript

1switch(typeof(resultData.a.a.b.c.d)){ 2 case "string": 3 ... 4 case "boolean": 5 ... 6 default: 7 8}

投稿2021/01/14 08:23

編集2021/01/14 08:48
umau

総合スコア805

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

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

takuya_am

2021/01/14 09:28

umau さん ご回答ありがとうございます。 > resultData変数の定義場所と利用箇所が同じ関数ローカルなら、オブジェクトのネストが深くても、ローカル変数に持ち直す事のパフォーマンス的なメリットはあまりないと思います。 そうねんですね! これはかなり気になっていたので教えて頂けてとてもありがたいです。 > 長くなりすぎると、コードが横に伸びて やっぱりそうですよね、私もこれはとても感じていて「resultData.hogehoge.fugafugafuga.xxxxxxxx」みたいなものを何回も書くのはどうかと思ったりすることが多々あります。 > 関数外に定義した変数を読む場合、関数スコープを手繰って行くコストがかかる場合があるため、オブジェクトのネストは関係なく、ローカルに持ち直すことはパフォーマンス的に有利になります。 なるほど、スコープを手繰るところは全然意識できていませんでした。 ローカルに持つ(持ち直す)というのはこういう意味でも重要なんですね。とても参考になりました、ありがとうございます!
guest

0

オブジェクトの同じプロパティから何度も値を取得する場合

本当に「何度も値を取得したい」のでしょうか?それとも、「値を得るのは1回でいいから、その値を何度も使いたい」のでしょうか?

JavaScriptではあまり例は多くないですが(この例とも関係ありません)、プロパティ参照自体も1つの演算ですので、やるたびに結果が異なることがありえます。いったん変数に確保したほうが、「同じ値について処理を行っている」ことがはっきりします。

投稿2021/01/14 06:48

maisumakun

総合スコア145184

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

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

takuya_am

2021/01/14 09:27

maisumakun さん ご回答ありがとうございます。 > 「値を得るのは1回でいいから、その値を何度も使いたい」のでしょうか? 説明不足で申し訳ありません。 そのケースが殆どです。 if 文などで比較されるオブジェクトの値は変わることは基本的にないですが、その結果によって他のプロパティの値を書き換えたりして別サーバーに返却することがあります。 > やるたびに結果が異なることがありえます。いったん変数に確保したほうが、「同じ値について処理を行っている」ことがはっきりします。 これはとても参考になりました。 同じオブジェクトでもどういった値なのかわかりやすくするために、変数に格納したほうが良いケースがあることを意識したいと思います。ありがとうございます。
guest

0

総じて要件によるです。

変数に入れると変数名ではオブジェクトのどの階層のプロパティにアクセスしているかまで一見してわからない

に関しては、必要なパターンもあれば、
必要ないパターンもありますので、やはり要件によります。
例えば、該当のオブジェクトを、
そのプログラム内では該当の値のみしか使わないなんて時は、
オブジェクト階層を識別する必要はありません。

ただし、オブジェクトの、他の階層の値を複合して使う必要がある、など、
その多階層に渡って、値が必要になる場合は、
階層を識別できる状態にしておいた方が、いいでしょう。

・変数に格納したほうが良い?

上記の通りです。

・変数に格納したほうが良い(悪い)場合の理由(速度が速いとか?)

特に変わらないパターンの方が多いです。
ただし、変数生成を、何万個とかする場合、循環参照など、メモリから解放できないような構文(メモリリーク)になっていた場合は、高確率で速度に影響します。
それ以外は、運用面上、要件上でどちらがいいか、でいいと思います。

・その他 メリット/デメリット が知りたいです。

上記の中で、回答になっているとは思います。
ただ、メリット・デメリットよりは、要件によって適した構文を組むことを意識するのが、エンジニアとして大事かと思います。

投稿2021/01/14 06:56

miyabi_takatsuk

総合スコア9528

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

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

takuya_am

2021/01/14 09:27

miyabi_takatsuk さん ご回答ありがとうございます。 > そのプログラム内では該当の値のみしか使わないなんて時は、オブジェクト階層を識別する必要はありません。 > その多階層に渡って、値が必要になる場合は、階層を識別できる状態にしておいた方が、いいでしょう。 確かにそうですよね!説明不足で後付になってしまいますが、私が直面しているケースでは、「多階層に渡って~」が多いので、識別できる状態(= 変数に格納せずそのまま参照)のほうが可読性も良い気がします。 > ただし、変数生成を、何万個とかする場合、循環参照など、メモリから解放できないような構文(メモリリーク)になっていた場合は、高確率で速度に影響します。 > それ以外は、運用面上、要件上でどちらがいいか、でいいと思います。 承知致しました。 変数に格納するにしても何万個も変数を生成するようなことは私の状況下ではなさそうですが、多階層に渡って値が必要になる場合は多々ありますので、多階層に渡る場合やそうではない場合も考慮しつつ、運用面、要件を意識してみます。 とても参考になりました!ありがとうございます。
guest

0

基本的に再代入して新しい名前を付けたほうがよいでしょう。このような名前を説明変数と呼びます。なんども同じ概念を使い回すのならば別の名前を与えたほうが認知負荷が低いのです。それにもし resultData.a.b.c.d.length じゃなくて resultData.a.b.c.e.length に変更だー!ってなったら大変ではありませんか?ですので一旦変数に格納したほうがよいでしょう。

ただし例外があります。それは特殊な働きにより result.a とアクセスするたびに結果が変わるやつです。この場合は毎回その名前でアクセスしなければいけません。ドキュメントに書いてあるはずなのでよく読みましょう(書いてなかったりするんだよな〜)。

投稿2021/01/14 06:47

A_kirisaki

総合スコア2853

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

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

takuya_am

2021/01/14 09:26

A_kirisaki さん ご回答ありがとうございます。 > resultData.a.b.c.d.length じゃなくて resultData.a.b.c.e.length に変更だー!ってなったら大変ではありませんか? そうですよね、私もプログラムを学び始めた頃によくそう教えられてきましたので、先入観の一つとして「変数に格納する」というものがありましたのでほっと出来ました。 > ただし例外があります。それは特殊な働きにより result.a とアクセスするたびに結果が変わるやつです。 他の方もおっしゃられているように、やはりここを意識しないとダメなんですね。私の意識化では欠けていましたので今後気をつけるように心がけたいと思います。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問