Как сохранить выражения функций JavaScript в памяти?

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

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

bye();            // Y

Прежде чем задать этот вопрос, я поискал в Google и нашел этот пост.

Затем я подумал, что до строки 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 , т.е. «имя» - это свойство объекта функции. Важно то, что это свойство доступно только для чтения . Хорошей практикой является использование 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);