公式アカウントからの投稿が始まります

同じ処理を使いまわすときに、関数を使いますが、下の例では関数を使ってますが、(どうやって使わずにかけるかわかりませんが)使う必要は無い気がします。
というか、アロー関数の働きが実感としてよくわからないので、下の例が理解出来ないんです。
で質問です
1.関数を使わずに書き直すとどうなりますか?
2. アロー関数ではなく、普通の関数(?)を使って書き直すとどうなりますか?
よろしくお願い

<script>
window.addEventListener('DOMContentLoaded', ()=>{
document.querySelector('#btn').addEventListener('click',()=>{
var file=document.querySelector('#temp').files[0];
if(file !==undefined){
var fr = new FileReader();
fr.addEventListener('load',e=>{
var blob=new Blob([e.target.result],{"type":file.type});
var binary=String.fromCharCode.apply("",new Uint8Array(e.target.result));
var base64="data:"+file.type+";base64,"+btoa(binary);
console.log(blob);
console.log(binary);
console.log(base64);
});
fr.readAsArrayBuffer(file);
}
});
});
</script>

A 回答 (1件)

こんにちは



ちゃんと理解しているわけではないのでたいした説明はできませんが、多少の助けにでもなれば・・・

先に、2のご質問の方について。
>2. アロー関数ではなく、普通の関数(?)を使って書き直すとどうなりますか?
アロー関数と通常のfunctionは完全には一致しませんが(thisの扱いが異なるなど)、概ねはfunctionの省略形と考えても良いと思います。
(詳しくは、以下を参照)
https://developer.mozilla.org/ja/docs/Web/JavaSc …
https://developer.mozilla.org/ja/docs/Web/JavaSc …

ご提示のスクリプトでは、3か所で使われていますが、いずれもイベント処理の設定部分で、引数の匿名関数の記述に使われています。
通常のfunction(){}形式に戻すのであれば、単純に、
window.addEventListener('DOMContentLoaded', function(){
document.querySelector('#btn').addEventListener('click',function(){
 ・・・・・
fr.addEventListener('load',function(e){
 ・・・・・

のような感じで置き換えればよさそうです。
勝手な想像ではありますが、わかり難くなっている原因は、どちらかと言えばアロー関数というよりも、匿名関数のネストにあるのではないでしょうか。


次に、1のご質問に関して。
>1.関数を使わずに書き直すとどうなりますか?
ご提示の例で、アロー関数が使われているのは、全てaddEventListener()メソッドの引数としてですが、このメソッドに要求される引数は
 target.addEventListener(type, listener[, options]);
となっており、このうちのlistenerが関数である必要があります。
ですので、イベント処理に関しては、「関数を使わず」というのは無理そうです。
似たような処理に、タイマー関連の処理やajaxの処理等が挙げられると思います。
https://developer.mozilla.org/ja/docs/Web/API/Ev …

上記は、addEventListener()メソッドを使う限りは無理という意味で、HTML要素内に直接 onclick="alert('OK');" などといった書き方をすれば、関数を用いなくても済みます。
と言っても、これはこれでわかりにくくなりますけれど・・・


匿名関数を使わずに、名前付き関数として定義する記述方法にすることで、処理構造が多少なりとも理解しやすくなるのではないかと思います。
例えば、ご提示のスクリプトを単純化して
 window.addEventListener('onload', e=>{
   /* 処理 A */
  target.addEventListener('click', e=>{
   /* 処理 B */
  });
 });
のような構成とした場合に、
これを個別の関数定義(funcA、funcB)に分解してみると、
 function funcB(e){ /* 処理 B */ }

 function funcA(e){
    /* 処理 A */
  target.addEventListener('click', funcB );
 }

 window.addEventListener('onload', funcA );

のように分けて記述することで、少しはわかりやすくなったような気にならないでしょうか?
(人にもよると思いますけれど)
    • good
    • 0
この回答へのお礼

fujillin さん、いつも回答ありがとうございます

>addEventListener()メソッドの引数としてですが、このメソッドに要求される引数は
> target.addEventListener(type, listener[, options]);
>となっており、このうちのlistenerが関数である必要があります。
>ですので、イベント処理に関しては、「関数を使わず」というのは無理そうです。

なるほど! 引数として関数を与える必要があったのですね。

>同じ処理を使いまわすときに、関数を使いますが、下の例では関数を使ってますが、(どうやって使わずにかけるかわかりませんが)使う必要は無い気がします。

の疑問が一気に解決しました!

window.addEventListener('DOMContentLoaded', ()=>{
は、日本語にすると、
 windowのイベントDOMContentLoadedに対し、以下の関数を割り当てる
と読むんですね。

定義した関数が、どこから呼ばれているのか見つからず悩んでしましたが、呼び出している部分がソースリストから見つからなくても良かったということですね(苦笑)

>これを個別の関数定義(funcA、funcB)に分解してみると、
なるほど、構造が見えてきました!

大変助かりました。

お礼日時:2019/10/30 22:42

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!