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

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

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

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

Q&A

解決済

3回答

1831閲覧

javascriptのaddEventListenerメソッドで、関数を設定する際に「関数名();」を記述しなくとも処理が実行される理由を教えて下さい。

y.o-teratail

総合スコア17

JavaScript

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

2グッド

3クリップ

投稿2019/12/16 06:37

前提・実現したいこと

javascriptを勉強中で、
今addEventListenerメソッドを学んでます。

そして、「click」によるクリックイベント処理の作り方で今つまづいておりまして、

下記のコードのようにgetElementByIdメソッドによる関数を設定する際に、
関数の呼び出しで必要な「関数名();」を記述せずとも処理が実行される理由を教えて下さい。

今までは関数を実行するには「関数名();」の記述が必須だと思ってました。

※コードではgetElementByIdメソッドになってますが、addEventListenerメソッドも記述の仕方は同じだと思いgetElementByIdにしました。

該当のソースコード

ボタン要素

<button id="btn">表示</button>

上記のボタンをクリックしたらイベント処理が発動して関数が実行される

let btn = document.getElementById('btn'); btn.addEventListener('click',()=> { console.log('クリックされました!'); });
ototakesan, miyabi_pudding👍を押しています

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

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

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

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

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

maisumakun

2019/12/16 06:46

> ※コードではgetElementByIdメソッドになってますが、addEventListenerメソッドも記述の仕方は同じだと思いgetElementByIdにしました。 どういう意味でしょうか?(getElementByIdとaddEventListenerではいろいろ異なる点があります)
m.ts10806

2019/12/16 07:21

これが「関数である」と分かってないということでしょうか…
miyabi_takatsuk

2019/12/16 07:54

m.ts10806さん > あ、もしかしてそういうことなのか・・・。
guest

回答3

0

ベストアンサー

「関数名();」の記述が必須だと思ってました。

そうでもないです。


たとえば、

js

1function test(){ 2 alert('test') 3} 4var func = test; 5 6func();

↑これは、関数名がtestですが、「test();」と書くことなく動作しています。
JavaScriptでは、関数を変数の中に納めることができるため、このようなことができます。


また、JavaScriptでは、関数を引数として取ることができます。

js

1function test(){ 2 alert('test') 3} 4function wrapper(f){ 5 f(); 6} 7wrapper(test);

↑このように、引数として関数を渡し、別の関数の中で実行させることができます。


またそもそも、JavaScriptでは名前のない関数を定義することができます。

js

1( function(){alert('test')} )()

↑関数式、または関数リテラルなどと呼ばれるもので、上記のコードのように即時実行をする時や、関数の引数として渡すときなどに使います。

投稿2019/12/16 07:45

Lhankor_Mhy

総合スコア37437

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

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

y.o-teratail

2020/01/08 07:44

すみません。 ベストアンサーとお礼をずっと忘れておりました。 回答ありがとうございました!
guest

0

おそらくコールバック関数に対するご質問でしょうか?
addEventListnerは第2引数にコールバック関数を指定します。

その際、

  • 予めコールバック用の関数をつくっておいて()なしで指定するか
  • 無名関数をコールバック用に指定します

投稿2019/12/16 07:03

yambejp

総合スコア117707

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

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

0

addEventListenerメソッドで、関数を設定する際に「関数名();」を記述しなくとも処理が実行される理由

古いイベントハンドラの設定/解除の実装の歴史を書くとこんな感じでした。

  1. handleEvent, releaseEvent (Netscape Navigator の実装)
  2. attachEvent, detachEvent (Internet Explorer の実装)
  3. addEventListener, removeEventListener (モダンな実装)

※ 2. 以降に着目してください。

IEがモダンな実装に変わるころ、addEventListener, removeEventListener はDOMオブジェクトにしか実装されておらず、自作のオブジェクトには、イベント伝搬機能を偽装する必要がありました。

で、以下のようなコードを書いて解決していました。

javascript

1// 自作の Ctor.prototype に mixin してイベント伝搬機能を偽装 2const MyEventDispatcher = { 3 listeners : {} 4, addEventListener: function( type, listener ) { 5 if( !this.listeners[type] ) { 6 this.listeners[type] = []; 7 } 8 this.listeners[type].push( listener ); 9 } 10, removeEventListener: function( type, listener ) { 11 var index = this.listeners[type].indexOf( listener ); 12 if( !~~index ) { 13 this.listeners.splice( index, 1 ); 14 } 15 } 16, dispatchEvent: function( event ) { 17 var self = this; 18 var type = event.type; 19 var listeners = this.listeners[type]; 20 21 for( vae i=0,l=listeners.length; i<l; ++i) { 22 var listener = listeners[i]; 23 listener.call( self, event ); 24 } 25 } 26};

無名関数でも良い理由

Document Object Model Events では、ご質問の無名関数でも良い理由に該当する内容は見当たりませんが、上記の偽装方法のように listeners[type] = listenr の形で イベントリスナ(関数オブジェクトの参照)が内部で保持されているのだとしたら、関数の名前は必要ないと考えられます。

投稿2019/12/16 07:38

AkitoshiManabe

総合スコア5434

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

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

miyabi_takatsuk

2019/12/16 07:45

> 上記の偽装方法のように listeners[type] = listenr の形で イベントリスナ(関数オブジェクトの参照)が内部で保持されているのだとしたら、関数の名前は必要ないと考えられます。 めちゃ納得です。よく考えたらそうですね。 他の無名関数実行の理屈もよくわかった気がします。 横槍失礼しました。
miyabi_takatsuk

2019/12/16 08:15

おお・・・。 お役に立てて光栄です。 以前私自身がかなりひっかかった部分で、teratailでご指摘を受けて、 勉強していって理解できた部分なんです。 JavaScriptの参照がどういうものか、どういう仕様なのか理解していくと、いろいろと見えてくるものがありますよね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問