Jak zachować w pamięci wyrażenia funkcji JavaScript?
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
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).
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 const
zamiast let
wyrażenia funkcji, a także, jeśli to możliwe, spróbuj nazwać debugowanie funkcji, które jest łatwe na stosie wywołań
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);