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

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

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

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

JavaScript

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

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

1回答

2109閲覧

グローバル変数が表示されない

ringoame49

総合スコア46

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

JavaScript

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

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2020/08/20 12:36

編集2020/08/21 09:23

質問失礼します。

現在位置情報から住所を検索する逆ジオコーディングを行っています。

コードはほぼコピペで動かなかった部分だけをいじりました。
下記コードを実行するとグローバル変数が表示されません。
またこのコードは必要?と気になる部分があります。
下記がコードです。

<body> <div id="result"></div> <div id="result2"></div> </body> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> <script type="text/javascript" src="https://maps.google.com/maps/api/js?key=XXXXXXXXXXXXXXXXXXXXXXXX"></script> <script type="text/javascript"> if( navigator.geolocation ){ navigator.geolocation.getCurrentPosition( function( position ){ var data = position.coords; //データの整理 var lat = data.latitude; var lng = data.longitude; var latLngInput = new google.maps.LatLng(lat,lng); var geocoder = new google.maps.Geocoder(); geocoder.geocode( {latLng: latLngInput}, function(results, status){ var address = ""; //この記述は必要? if (status == google.maps.GeocoderStatus.OK){ address = results[0].formatted_address; document.getElementById('result').innerHTML = address; }else if (status == google.maps.GeocoderStatus.ZERO_RESULTS){ alert("住所が見つかりませんでした。"); }else if (status == google.maps.GeocoderStatus.ERROR){ alert("サーバ接続に失敗しました。"); }else if (status == google.maps.GeocoderStatus.INVALID_REQUEST){ alert("リクエストが無効でした。"); }else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT){ alert("リクエストの制限回数を超えました。"); }else if (status == google.maps.GeocoderStatus.REQUEST_DENIED){ alert("サービスが使えない状態でした。"); }else if (status == google.maps.GeocoderStatus.UNKNOWN_ERROR){ alert("原因不明のエラーが発生しました。"); } } ); //元はここにdocument.getElementById('result').innerHTML = address;が記述されていた。 }, function( error ){ //エラーの処理 } ); } document.getElementById('result2').innerHTML = address; </script>

result2の部分が何も表示されません。
また、コピペ元もグローバル変数で表示していたと思います。(ソース内のコメントアウトの位置にdocument.getElementById('result').innerHTML = address;が記述されていた。)
またソース内のvar address = "";の記述は必要なのでしょうか?
あってもなくても結果は変わりません。

以上、なぜグローバル変数が表示されないのかとvar address = "";の記述が必要なのかをご教授いただけますと幸いです。
よろしくお願いいたします。

追記
現在のコード

<body> <div id="result"></div> <div id="result2"></div> </body> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> <script type="text/javascript" src="https://maps.google.com/maps/api/js?key=XXXXXXXXXXXXXXXXXXXXXXXX"></script> <script type="text/javascript"> if( navigator.geolocation ){ navigator.geolocation.getCurrentPosition( function( position ){ var data = position.coords; var lat = data.latitude; var lng = data.longitude; var latLngInput = new google.maps.LatLng(lat,lng); var geocoder = new google.maps.Geocoder(); geocoder.geocode( {latLng: latLngInput}, function(results, status){ if (status == google.maps.GeocoderStatus.OK){ address = results[0].formatted_address; document.getElementById('result').innerHTML = address; }else if (status == google.maps.GeocoderStatus.ZERO_RESULTS){ alert("住所が見つかりませんでした。"); }else if (status == google.maps.GeocoderStatus.ERROR){ alert("サーバ接続に失敗しました。"); }else if (status == google.maps.GeocoderStatus.INVALID_REQUEST){ alert("リクエストが無効でした。"); }else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT){ alert("リクエストの制限回数を超えました。"); }else if (status == google.maps.GeocoderStatus.REQUEST_DENIED){ alert("サービスが使えない状態でした。"); }else if (status == google.maps.GeocoderStatus.UNKNOWN_ERROR){ alert("原因不明のエラーが発生しました。"); } } ); }, function( error ){ //エラーの処理 } ); document.getElementById('result2').innerHTML = address; } </script>

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

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

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

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

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

guest

回答1

0

ベストアンサー

解決策

html

1<body> 2 <div id="result"></div> 3 <div id="result2"></div> 4</body> 5 6<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> 7<script type="text/javascript" src="https://maps.google.com/maps/api/js?key=XXXXXXXXXXXXXXXXXXXXXXXX"></script> 8<script type="text/javascript"> 9if (navigator.geolocation) { 10 navigator.geolocation.getCurrentPosition(function (position) { 11 var data = position.coords; 12 var lat = data.latitude; 13 var lng = data.longitude; 14 var latLngInput = new google.maps.LatLng(lat,lng); 15 var geocoder = new google.maps.Geocoder(); 16 17 geocoder.geocode({ latLng: latLngInput }, function (results, status) { 18 var address = ""; 19 20 if (status == google.maps.GeocoderStatus.OK) { 21 address = results[0].formatted_address; 22 23 document.getElementById("result").innerHTML = address; 24 } else if (status == google.maps.GeocoderStatus.ZERO_RESULTS) { 25 alert("住所が見つかりませんでした。"); 26 } else if (status == google.maps.GeocoderStatus.ERROR) { 27 alert("サーバ接続に失敗しました。"); 28 } else if (status == google.maps.GeocoderStatus.INVALID_REQUEST) { 29 alert("リクエストが無効でした。"); 30 } else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) { 31 alert("リクエストの制限回数を超えました。"); 32 } else if (status == google.maps.GeocoderStatus.REQUEST_DENIED) { 33 alert("サービスが使えない状態でした。"); 34 } else if (status == google.maps.GeocoderStatus.UNKNOWN_ERROR) { 35 alert("原因不明のエラーが発生しました。"); 36 } 37 38 document.getElementById("result2").innerHTML = address; 39 }); 40 }, function (error) { 41 //エラーの処理 42 }); 43} 44</script>

なぜ変数addressが表示されないのか

ユーザー定義変数(navigatorなど元々定義されていない変数、コードの中で定義している変数)addressを利用しようとしているスコープでaddress変数が有効でないからです。

変数を扱う場合には、その変数が有効な範囲(スコープといいます)を意識しなければなりません。

質問で提示されているコードには、画像で示す通り、Scope 1からScope 5-7まで12のスコープが存在し、address変数はvar文で宣言されているので、Scope 4のみで有効になります。

そのため、address変数を利用しようとしている式をScope 4内の各処理の後ろに移動させると期待通りの動作になります。

各スコープで有効なユーザー定義変数を以下列挙しますので、address変数を利用しようとしているScope 1ではaddress変数が有効ではないことを確認してください。

イメージ説明

Scope 1

  • なし

Scope 2

  • なし

Scope 3-1

  • data
  • lat
  • lng
  • latLngInput
  • geocoder

Scope 3-2

  • error

Scope 4

  • data (Scope 3-1から継承)
  • lat (Scope 3-1から継承)
  • lng (Scope 3-1から継承)
  • latLngInput (Scope 3-1から継承)
  • geocoder (Scope 3-1から継承)
  • results
  • status
  • address

Scope 5-1からScope 5-7

  • Scope 4と同じ

var address = "";の記述が必要なのか

あってもなくても結果は変わりません。

結果はおっしゃる通り変わりませんが、address変数のスコープが変わります。

var文での変数宣言がある場合、address変数は宣言した関数スコープ(Scope 4)内で有効になります。

var文での変数宣言がない場合、address変数はグローバル変数となり、全てのスコープで有効になりますが、if (status == google.maps.GeocoderStatus.OK)の条件式を満たさない場合、ReferenceErrorになってしまうかと思われます。

投稿2020/08/21 05:57

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

ringoame49

2020/08/21 06:43

ご解答ありがとうございます!!! var文での変数宣言がある場合、address変数は宣言した関数スコープ(Scope 4)内で有効になります。 var文での変数宣言がない場合、address変数はグローバル変数となり、全てのスコープで有効になりますが、if (status == google.maps.GeocoderStatus.OK)の条件式を満たさない場合、ReferenceErrorになってしまうかと思われます。 とありますが、var文での変数宣言の部分を削除しても「result2」の部分には何も表示されません。 コンソールでもUncaught ReferenceError: address is not definedのエラーが検出されています。 しかし「result」の方は表示されているのでif (status == google.maps.GeocoderStatus.OK)の条件式を満たしていると思うのですが何か解釈は間違っておりますでしょうか?
退会済みユーザー

退会済みユーザー

2020/08/21 09:10

現状のソースを質問本文に追記してもらえますか?
ringoame49

2020/08/21 09:23

ありがとうございます。 追記いたしました。
退会済みユーザー

退会済みユーザー

2020/08/21 09:53

`document.getElementById("result2").innerHTML = address;`をScope 4に移動してください。 ソース内の処理は必ず上から順に実行されるわけではありません。 今回の例だと、`getCurrentPosition`のメソッドは現在位置の取得を待たずに次の処理`document.getElementById('result2').innerHTML = address;`を実行してしまいます。 そのため、現在位置取得後に実行されるScope 4内の処理は、`document.getElementById('result2').innerHTML = address;`の実行後に行われます。 現状のソースではScope 4で`address`変数に値を代入していますので、`document.getElementById('result2').innerHTML = address;`実行時にReferenceErrorとなります。 つまり、実行の順番が 1. `getCurrentPosition` 2. `document.getElementById('result2').innerHTML = address;` 3. `address = results[0].formatted_address;` になっているということです。 どうしても`document.getElementById("result2").innerHTML = address;`を一番下に書きたければ、`async/await`を利用して実装し直す方法もありますが、 簡単ではないのであまりお勧めはしません。
ringoame49

2020/08/21 11:48

度々のご解答ありがとうございます!! ソース内の処理は必ず上から順に実行されるわけではありません。 そうだったんですね。 また1つ勉強になりました。 今回は問題、疑問が解決でき、更に貴重なことまで教えていただきありがとうございました。 また機会がありましたらよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問