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

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

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

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

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

Q&A

解決済

6回答

1555閲覧

javascript のエラー制御と PHPのエラー制御演算子について

ssmxgo

総合スコア178

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

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

1グッド

1クリップ

投稿2019/05/17 06:55

編集2019/05/18 08:30

ご覧になっていただき幸いです

さて、javascriptでオブジェクトを参照する処理で、存在しない項目を指定した場合、エラーになって処理が止まってしまします。

エラー原因は単純に存在しない項目を参照しているところに原因がわかっているため、PHPでいうところのエラー制御演算子的な処理で空データを設定したいと考えましたが、よくわかりません

try catch を使うということになるのでしょうか?

javascrpt

1objReports={"reports":{"author":{"id":101,"name":"人名"}}}; 2console.log(objReports); 3//レポート入力者 4$('#author_name' ).val( objReports['reports']['author']['name'] );

html

1<input id="author_name">

だと
Uncaught TypeError: Cannot read property 'name' of undefined
のようなエラーを吐き出しスクリプトが終了します。

ニュアンスが伝わるかわかりませんが、これをPHPのエラー制御演算子如くスルーする方法はないでしょうか?

php

1$author_name = @objReports['reports']['author']['name'];

ベストプラクティスをご教授ください

Lhankor_Mhy👍を押しています

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

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

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

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

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

x_x

2019/05/17 07:02

突然'repots'が出てきたのですが、'reports'と書くべきところを'repots'と書いてエラーになったということでしょうか?
ssmxgo

2019/05/17 08:05

すみません、記述ミスですし、間違えていましたので訂正します
x_x

2019/05/17 08:07

現状では質問内容が把握できないので訂正ではなく修正をお願いします。
ssmxgo

2019/05/18 08:31

なかなか伝えるということは難しいです。改めて修正させていただきましたが正しく伝えられるものになってるのかどうか…????
guest

回答6

0

ベストアンサー

まず、PHPの@は悪手なので使わないようにしましょう。
それエラーを無理やり握りつぶしてるだけなのでパフォーマンス的な話でちゃんと精査して取りに行く方が速度も出ます。


try catch を使うということになるのでしょうか?

try-catchの使い所さんは結構難しいのです。
基本的に完成したシステムにはバグがなくなるはずです。

tryつまり挑戦しなければならない場面で使いましょう。
具体的にはネットワークアクセス等で先方のWebサーバが生きてるかどうか保証しかねるようなケースで使用すべきです。

しかし、JavaScriptに於いて、他のシステムに問い合わせるという場面は基本的に非同期処理です。
第一引数errになるコールバック関数内でやれという思想で運用されていますから、
try-catchを使うタイミングというのは殆ど存在しません。

Promiseも.then(fn).catch(fn)でコントロールしますから
こちらもtry-catchの使用タイミングというのはほぼ皆無です。

Promiseの糖衣構文になるES7で追加されたasync/await構文では
try-catchを使うと自動的にPromiseのrejectを叩いて、.catch(fn)で取り出したような動作になるはずなので、そのくらいでしょうか?


原因もわかってるようなので解決策だけ、
基本はLodashRamdaなどの値操作の達人なライブラリを使うべきです。

Lodashならばget
Ramdaならばpathで苦労もなく取得できます。

nullundefinedが挟まり、
これらの値はプロパティを所持出来ずアクセスするとエラーになるはずですが…
存在しないパスが間に挟まっていても難なく取ってこれるのがわかるはずです。

このようにLodashやRamdaはPHPのビルトイン関数に匹敵する便利ライブラリですから、
せめてどちらかは採用して何時でも使えるようにしておくべきでしょう。
有名で流行っているLodashがオススメです。


ですが、ライブラリを実装出来ないケースでは下記のような関数を作って対処することをすすめます。
やっつけなので動作を保証してくださいという話なら
責任持てないので上記のようなライブラリを検討してください。

JavaScript

1const get = (obj, path) => 2 path.split('.').reduce((obj, path) => 3 obj == null ? undefined : obj[path] 4 , obj); 5 6// 使い方 7var obj = { 8 taro: {id: 1, age: 18, score: 80}, 9 jiro: {id: 2, age: 17, score: 85}, 10 busaro: {id: 3, age: 16, score: 75}, 11}; 12console.log(get(obj, 'taro.age')); 13// 18 14console.log(get(obj, 'taro.hoge.piko')); 15// undefined <- 存在しないパスが途中にくるが別にエラーにはならない

投稿2019/05/17 07:33

編集2019/05/17 07:36
miyabi-sun

総合スコア21158

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

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

ssmxgo

2019/05/17 08:23

みなさま、ホント神様みたいな方ばかりです PHP の@は速度面の問題とエラーとして認識できない問題等で賛否が多くあるのは存じておりますが、ご提示頂いたライブラリのようなものは一日かけても生み出せませんw 本当にありがとうございます。 どうもPHPで悪い癖がついているのかjavascriptにうまく馴染めません みなさんにベストアンサーをお返ししたいのですが最上級アンサーということで もっとも懇切丁寧に記述いただいた @miyabi-sun にお捧げします ありがとうございました
guest

0

今すぐは使えないですが、新機能としてoptional chainingが提案中です

javascript

1$('#author_name' ).val( objReports?.reports?.author?.name );

投稿2019/05/17 07:11

maisumakun

総合スコア145183

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

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

ssmxgo

2019/05/17 08:08

ありがとうございます やはり、エラー制御演算子的なものって需要があるってことですね 早く一般化してほしいです!
guest

0

可読性が悪いのと、Falsy値をどうするのか、という問題がありますが、こういう書き方はどうでしょうか。

js

1( ( objReports['reports'] || {} )['author'] || {} )['name']

js

1objReports['reports'] && objReports['reports']['author'] && objReports['reports']['author']['name']

ECMAScriptにも safe navigation operator が欲しいですね。

投稿2019/05/17 07:39

Lhankor_Mhy

総合スコア36074

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

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

maisumakun

2019/05/17 07:41

optional chainingはまだStage 1とのことで、いったいいつになるのかわからないですね…
Lhankor_Mhy

2019/05/17 08:09

2、3年はかかる感じなんでしょうね。パイプ演算子はいつ来るんだろう……
ssmxgo

2019/05/17 08:15

ありがとうございます yambejpさんの記述に通じる構文ですね φ(..)
guest

0

オブジェクトのネストでどこでtypoしているかあやしいなら
try-catchなんでしょうけど、逆にどこが問題かわからないのは
気持ち悪い気がする

PHPの@エラー回避も滅多なことで使わないほうが身のため

とはいえどうしてもというならこう

javascript

1var name; 2objReports={"reports":{"author":{"id":101,"name":"人名"}}}; 3name=((objReports['repots']||{})['authr']||{})['nam']; 4console.log(name); 5name=((objReports['repots']||{})['author']||{})['name']; 6console.log(name); 7name=((objReports['reports']||{})['authr']||{})['name']; 8console.log(name); 9name=((objReports['reports']||{})['authr']||{})['nam']; 10console.log(name); 11name=((objReports['reports']||{})['author']||{})['name']; 12console.log(name); 13

投稿2019/05/17 07:30

yambejp

総合スコア114784

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

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

ssmxgo

2019/05/17 08:13

すごいなぜ正しい挙動するのか素人にはわかりませんが、すごいです ありがとうございます
guest

0

その項目が存在するかどうかを判断して、存在しなければ以降の処理をスキップするように組めばよろしい

投稿2019/05/17 07:01

y_waiwai

総合スコア87749

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

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

ssmxgo

2019/05/17 08:07

ありがとうございます やはりそういう形でのアプローチしかないのですかね
y_waiwai

2019/05/17 08:44

if で済むところをtry catch使ったところで何もメリットはないです コード量が減るわけでもなければ、実行時間はかえって増える、動作を追いかけづらくなる、ということで。 #そこをあえて使う、というテもありだとは思いますが
ssmxgo

2019/05/18 08:15

ありがとうございます
guest

0

PHPのエラー制御演算子(@)は、エラーを画面に表示しないだけで、内部的にはエラーになっています。
多分、ご覧になることはないと思いますが、Apache等のWebサーバーのエラーログに大量にエラーが出力されていますよ。

投稿2019/05/21 02:55

TomoakiNagahara

総合スコア108

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

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

ssmxgo

2019/05/24 01:13

回答おそくなりました なるほど、@はエラー制御演算子、ではあるものの その実態はエラーメッセージ抑止演算子なのですね それは実行速度は遅くなるわけです
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問