JavaScript関数式をメモリに保持する方法は?

Nov 23 2020
let sayBye = function () {
    console.log(`Bye`);
}

let bye = sayBye;   
sayBye = null;    // X

bye();            // Y

この質問をする前に、私はグーグルで検索し、私はこの投稿を見つけました。

次に、X行の前に次のような構造があると思いました。


sayBye ---------------                                              
                      |      
                      |  => function() {....}
                      |
bye-------------------

x行の後、私はそれが次のようであると思いました:

sayBye                        MEMORY                                      
                            
                      |  => function() {....}
                      |
bye-------------------

しかし、Firefox開発ツールでさようならを書いたとき、私はこれを見ました

どうしてそれは可能ですか?私が書いたときlet bye = sayBye;、sayByeはコピーされましたか?

let sayBye = function () {
    console.log(`Bye`);
}

let bye = sayBye;   
sayBye = null;    // X

bye();            // Y

console.log(bye);

回答

5 sp00m Nov 23 2020 at 17:53

から https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Inferred_function_names:

変数とメソッドは、その構文上の位置から無名関数の名前を推測できます(ECMAScript 2015の新機能)。

ChromeとFirefoxはどちらも"sayBye"印刷時に表示されますbye.name


個人的な実験から、Chromeコンソールはbye.toString()要求時byeに表示しますが、Firefoxは関数の推測された名前を表示するカスタム出力を表示します(名前を知っていると通常はデバッグに役立つため、これは確かに理にかなっています)。

3 RanjeetThorat Nov 23 2020 at 18:43

関数はオブジェクトであるため、割り当てx = yはコピーされません。入手したこのNodejsを試しました

Bye
[Function: sayBye]

関数に名前を付けない場合、JSは自動的に関数に名前を追加します。ES6ではmyFunction.nameを使用して関数の名前を確認できます。つまり、「name」は関数オブジェクトのプロパティです。重要なことは、これが読み取り専用のプロパティであるということです。関数式を使用するconst代わりにlet使用することをお勧めします。また、可能であれば、呼び出しスタックで関数のデバッグに名前を付けるのは簡単です。

2 FZs Nov 23 2020 at 18:16

関数の名前に混乱しています。

記憶の事はあなたが思ったのとまったく同じように起こります。

ただし、関数には明示的な名前がなかったため、ブラウザは関数に暗黙の名前を付けました。これは、最初に割り当てられた変数またはオブジェクトプロパティの名前で、この場合はsayByeです。

次に、別の変数に割り当てられますが、名前は変更されません。

明示的な名前を付けると、これを確認できます。

//  Explicit name ----vvvv
let sayBye = function myFn() {
    console.log(`Bye`);
}

let bye = sayBye;   
sayBye = null;    // X

bye();            // Y

console.log(bye);