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

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

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

スコープとは、プログラム内で変数名など、参照可能な有効範囲のことを指します。

JavaScript

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

Q&A

解決済

4回答

4358閲覧

JavaScript 変数に代入したDOM要素が関数のブロックスコープの影響を受けないのは何故?

gucha

総合スコア55

スコープ

スコープとは、プログラム内で変数名など、参照可能な有効範囲のことを指します。

JavaScript

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

1グッド

1クリップ

投稿2018/01/14 00:24

DOM要素以外はちゃんとブロックスコープの影響を受けてスコープ外からはアクセスできないようになっていると思います。
DOM要素だけはスコープ外からもアクセスでき、別関数内からも参照できました。

何故と言われてもそういう仕様だから、と言われればそれで納得するしかないとも思いますがモヤモヤします。他のObjectタイプではこのような動作にならない?と思うのでDOM要素に特別な何かがあるのでしょうか?

またこのような仕様を知る場所をmozillaのリファレンスぐらいしか知らないので、細かな仕様を調べる場合に見るべきサイトなども教えて欲しいです。

javascript

1function test1(){ 2 const box = document.querySelector('#box') 3 const num = 1; 4 console.log(box) //#box要素 5 console.log(num) //1 6} 7 8function test2(){ 9 console.log(box) //#box要素 10 console.log(num) //ReferenceError: num is not defined 11} 12 13test1() 14console.log(box) //#box要素 15test2()
defghi1977👍を押しています

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

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

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

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

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

guest

回答4

0

ベストアンサー

<input id="box">と言ったようにHTML内にid値が振られたノードが存在した場合, スクリプト側でwindow.boxとしてアクセス可能となります. グローバル変数boxはここからwindowを省略したものと考えられます.

参考
https://html.spec.whatwg.org/multipage/window-object.html#accessing-other-browsing-contexts

NOTE:変数boxの名称をbox1としてどうなるか試してみて下さい.

JavaScript

1function test1(){ 2 const box1 = document.querySelector('#box') 3 const num = 1; 4 console.log(box) //#box要素 5 console.log(num) //1 6} 7 8function test2(){ 9 console.log(box1) //#box要素 10 console.log(num) //ReferenceError: num is not defined 11} 12 13test1() 14console.log(box1) //#box要素 15test2() 16

投稿2018/01/14 00:46

defghi1977

総合スコア4756

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

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

gucha

2018/01/14 03:15

ありがとうございます。スッキリしました。 同様に教えていただいた他の方々もありがとうございました! 参考サイトが一度も見たことがなく有用だと思ったので、今回はこちらをベストアンサーとさせてもらいます。
guest

0

idがつけられたDOM要素は、そのidでグローバルに展開されます。

グローバルスコープとローカルのスコープにおいて同名の変数がある場合、ローカルが優先されます。
変数名をidと同じboxとしているため混乱をまねいていると思いますが、
test1()内でbox変数を定義して代入していますが、このbox変数もブロックでしか有効ではありません。
test2()はグローバルに展開されたboxを参照しています。

投稿2018/01/14 00:44

turbgraphics200

総合スコア4267

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

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

0

こんにちは。

test2() のほうの、

javascript

1console.log(box)

で表示しているbox は、test1() で作られた const box ではなく、
windowオブジェクトの box プロパティを指定していることになります。

以下のスクリプトの、Console ログを確認してみてください。

https://jsfiddle.net/jun68ykt/6ugbreht/

以下の投稿もご参考まで。

nakajmgさん@Qiita: HTML内でIDをつけた要素はJavaScriptのグローバル変数に格納される


追記

上記の説明で

windowオブジェクトの box プロパティを指定していることになります。

と書きましたが、厳密には、

window.box と、window** のプロパティのようにアクセスできる**

といったほうがよいかもしれません。

以下で、window.hasOwnProperty('box') は (Chrome だと) false になりました。

https://jsfiddle.net/jun68ykt/6ugbreht/1/

自分はざっくり、「idをつけた要素はグローバル変数になる」で覚えていました。

投稿2018/01/14 00:41

編集2018/01/14 01:06
jun68ykt

総合スコア9058

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

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

defghi1977

2018/01/14 01:16

FireFoxだとtrueとなるので実装依存の極めて微妙な仕様かもしれません
jun68ykt

2018/01/14 01:24

defghi1977 さん > FireFoxだとtrueとなる んですね。微妙ですね。 だいぶ古い投稿ですが、stackoverflow で以下をみつけました。 Do DOM tree elements with ids become global variables? https://stackoverflow.com/questions/3434278/ 一番多くいいねを得ている回答を読んでみても、やはりブラウザ依存の問題っぽいですね。
gucha

2018/01/14 03:13

ブラウザ依存の仕様もあったのですね。 次から質問するときは他のブラウザでも確認しようと思います。
guest

0

アクセス出来ませんよ。アクセス出来たというのは勘違いでは?

投稿2018/01/14 00:40

otn

総合スコア84538

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問