hasu112358
@hasu112358

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

記述する順番で関数が動かなくなる理由を知りたい

1つ目のコードは動くのに2つ目のコードが動かない理由を知りたいです。

最近JavaScriptを勉強し始めたものです。
プログラミング自体初めてです。

1つ目のコードは動くのに2つ目のコードが動かない理由を知りたいです。
確かJavaScriptは上に記述されているコードから実行されるが関数はどこで呼び出しても動くと聞きました。実際1つ目の関数は動いています。

該当するソースコード

1つ目

resetBtn.addEventListener("click",()=>{
    reset();
})
const reset= ()=>{
//実際はここに処理を記述
}

2つ目

resetBtn.addEventListener("click",reset)
const reset= ()=>{
//実際はここに処理を記述
}

また、2つ目を実行すると以下のようなエラーメッセージが出ます。

Uncaught ReferenceError: Cannot access 'reset' before initialization

自分で試したこと

宣言→呼び出しの順番で記述すれば動きました。

const reset= ()=>{
    //実際はここに処理を記述
}
resetBtn.addEventListener("click",reset)

また、アロー関数が問題なのかと思いましたが(動作が普段の関数と違うイメージ)、関数式に戻しても2つ目と同じく動きませんでした。

resetBtn.addEventListener("click",reset)
const reset = function(){
    //実際はここに処理を記述
}

追加で知りたいこと

JavaScriptでは(プログラム言語を書くときは)こう言ったことが起こらないようにまとまった宣言のセクション→実行のセクションの順番で書いた方がいいのでしょうか。

質問は初めて利用するので使い方があっているかわかりません。どうかよろしくお願いします。

0

4Answer

下記コードのボタン押下時の動きの違いで、処理の違いが少しイメージしやすくなるかもしれません。
理解の助けになれば幸いです。

See the Pen Untitled by yotty (@yotty) on CodePen.

1Like

Comments

  1. @hasu112358

    Questioner

    @Vercleneさんの説明併せて少し理解できました。けど正直混乱という感じです。自分はグローバルスコープあたりの知識、まだ知らないことが多すぎると感じました。このあたり理解できるようになってからまた戻ってきます。またなにかわからないことがあったら質問させてください。サンプルコードまでありがとうございました!

エラーメッセージでググるといろいろヒットすると思いますがやってみました? 例えば下記:

ReferenceError: can't access lexical declaration`X' before initialization
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Errors/Cant_access_lexical_declaration_before_init

"let または const 宣言が定義される前にアクセスされたときに発生します。" <= なので「2 つ目」のコードの一行目の reset でそのエラーが出ているはずです。

Uncaught ReferenceError: Cannot access ” before initializationの原因と対処法
https://web-engineer-wiki.com/javascript/error-cannot-access/

他にもいろいろヒットするので自分でもやってみましょう。

0Like

Comments

  1. @hasu112358

    Questioner

    エラーメッセージでググる、まったく発想にありませんでした。しかしこういったエラーに対処する方法としてはメジャーなのですね。初めてで左右もわからないので助かりました。ありがとうございます!

  2. ググって調べるというのは、当たり前に、一番最初に、質問する前にやるべきことです。自力でググって調べて解決できるというのは開発者として大変重要なスキルだと認識してください。ググるためのキーワードが問題で、それによっては有用な記事がヒットしないということがままありますが、エラーメッセージはキーワードとして有用です。

プログラム初心者はみんな、エラーメッセージを呪いの文字のように嫌いますよね。直視したら死んでしまう〜、みたいな。
でも実は全く逆です。
エラーメッセージはあなたを「プログラムが動かない地獄」から救い上げる仏の言葉なのです。
まずは怖がらずにGoogle翻訳してみましょう。
意味が分からなかったらGoogle検索してみましょう。

0Like

Comments

  1. @hasu112358

    Questioner

    赤字でいきなり英語でエラー表示されると怖くて...
    早い段階でエラーをそのままGoogle翻訳という画期的な解決法を知れたのは大きな収穫でした。Qiitaで質問してよかったです。ありがとうございます!

だいたい @YottyPG さんのスニペットで何が起こってるかは追えるかもしれませんので私からは補足だけ.

JavaScriptでは(プログラム言語を書くときは)こう言ったことが起こらないようにまとまった宣言のセクション→実行のセクションの順番で書いた方がいいのでしょうか。

単純に宣言位置という意味ではC#のようにより厳格にスコープと宣言位置を制限している言語もありますが,そもそもグローバルスコープの状態に依存するような実装はやめろという話になってきます.ことJavaScriptは諸々そういった問題にかなり気を使わなければならない事情があり,IIFEやESModuleなどでスコープを制限したり,varを廃した実装を推進されてきた経緯があります.
const宣言やモジュール化がされていれば幾分かは安心ですが,基本的には「無意識にベタ書きするのはやめましょう」というのが原則だと思います.

確かJavaScriptは上に記述されているコードから実行されるが関数はどこで呼び出しても動くと聞きました。

というような実行機序もスコープもhoistingもへったくれもない一言を鵜呑みにするとえらい目にあいますので,早めに忘れてください.

0Like

Comments

  1. @hasu112358

    Questioner

    まだまだ始まったばかりなので今はすべてを理解できませんでした。すみません。勉強中軽視していたスコープや僕の見たことのない関数の宣言であるvarなどあり一朝一夕で理解できるものでないと覚えました。しかし勉強を続けていればじきに理解できるようになるのでしょう。早い段階で重要な要素に触れられてよかったです。理解できるよう引き続き勉強頑張ります。ありがとうございます!

Your answer might help someone💌