Jak zachować w pamięci wyrażenia funkcji JavaScript?

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

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

bye();            // Y

Zanim zadałem to pytanie, szukałem w google i znalazłem ten post.

Wtedy pomyślałem, że przed linią X struktura wygląda podobnie:


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

Po linii x pomyślałem, że wygląda to tak:

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

Ale kiedy napisałem do widzenia w narzędziach programistycznych Firefox, zobaczyłem to

Jak to jest możliwe? Kiedy napisałem, let bye = sayBye;czy SayBye zostało skopiowane?

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

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

bye();            // Y

console.log(bye);

Odpowiedzi

5 sp00m Nov 23 2020 at 17:53

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

Zmienne i metody mogą wywnioskować nazwę funkcji anonimowej z jej pozycji składniowej (nowość w ECMAScript 2015).

Chrome i Firefox działają "sayBye"podczas drukowania bye.name.


Z osobistych eksperymentów konsola Chrome pokazuje, bye.toString()gdy prosi o to bye, podczas gdy Firefox wyświetla własne wyjście, w którym wyświetla wywnioskowaną nazwę funkcji (co ma sens, ponieważ znajomość nazwy zwykle pomaga w debugowaniu).

3 RanjeetThorat Nov 23 2020 at 18:43

Funkcje są obiektami, więc przypisanie x = y nie jest kopiowane. Wypróbowałem ten Nodejs, który dostałem

Bye
[Function: sayBye]

Jeśli nie nazwiesz funkcji, JS automatycznie doda do niej nazwę. W ES6 możesz sprawdzić nazwę funkcji używając myFunction.name , tzn. 'Name' jest właściwością obiektu funkcji. Ważne jest to, że jest to właściwość tylko do odczytu . Dobrą praktyką jest używanie constzamiast letwyrażenia funkcji, a także, jeśli to możliwe, spróbuj nazwać debugowanie funkcji, które jest łatwe na stosie wywołań

2 FZs Nov 23 2020 at 18:16

Jesteś zdezorientowany nazwą funkcji.

Pamięć dzieje się dokładnie tak samo, jak myślałeś.

Jednak funkcja nie miała jawnej nazwy, więc przeglądarka nadała funkcji niejawną nazwę , czyli nazwę zmiennej lub właściwości obiektu, do której została najpierw przypisana, w tym przypadku sayBye.

Następnie zostaje przypisany do innej zmiennej, ale nazwa się nie zmienia.

Możesz to zobaczyć, jeśli podasz mu wyraźną nazwę:

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

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

bye();            // Y

console.log(bye);