Закрытие параметров функции JavaScript, в зависимости от того, как функция передается в качестве параметра, я вижу два разных результата

#javascript #node.js #ecmascript-6 #closures

Вопрос:

Я полагаю, что сталкиваюсь с проблемой закрытия при передаче функции в качестве параметра моей функции. Я включаю два фрагмента, которые, я не совсем уверен, дают разные результаты

В верхней части файла:

 let printPizza = () => console.log('pizza')
 
 function closureQuestion(fn) {
 printPizza = () => console.log('hamburger')
 fn()
}
 

Они должны быть запущены по порядку, иначе printPizza мутирует и должна быть переопределена

 closureQuestion(printPizza)
 

^ регистрирует пиццу (не знаю почему)

 closureQuestion(() => printPizza())
 

^ гамбургер из бревен

Любая помощь была бы признательна, я прочитал несколько примеров закрытия (просто предположение о том, с чем я сталкиваюсь), и я не понимаю.

Комментарии:

1. В первом случае у вас есть прямая ссылка на функцию, которая печатает pizza . Во втором случае вы этого не делаете и изменяете функцию, которая будет вызвана до ее вызова.

2. @VLAZ можно ли подробнее рассказать? во втором примере я не использую ссылку на функцию?

3. Не прямая ссылка. У вас есть косвенный, потому что вы передаете анонимную функцию, которая будет вызывать printPizza . Однако printPizza может изменяться между создаваемой анонимной функцией и вызываемой анонимной функцией. Первый пример-это как дать кому-то документ для печати. Документ не изменится — печать всегда одна и та же. Второе похоже на предоставление им URL-адреса: www.myDocument.com останется прежним, но содержимое может измениться, поэтому то, что вы печатаете, может отличаться.

Ответ №1:

В первой версии вы получаете значение printPizza перед вызовом функции. Параметру fn присваивается исходное значение printPizza , и переназначение переменной не влияет на параметр. Это ничем не отличается от того, чтобы делать:

 let printPizza = 1;
let fn = printPizza;
printPizza = 2;
console.log(fn); // this will log 1, not 2
 

Во второй версии вы не выполняете оценку printPizza до тех пор, пока не будет выполнена функция обратного вызова, поэтому она будет использовать последнее значение переменной.

Комментарии:

1. Но функции не передаются по ссылке. Поскольку printPizza подвергается манипуляциям, не следует ли fn() выводить другой результат?

2. @TusharShahi: JavaScript-это язык передачи значений . Это не имеет ничего общего с объектами, являющимися значениями ссылочного типа.

3. @FelixKling сравнивает две функции внутри closureQuestions, используя ‘===’. Они равны. Проверить codepen.io/tusharshahi/pen/QWpJreG?editors=1112

4.@Тушаршахи: Да, но это не имеет никакого отношения к тому, о чем вы спрашивали. Присвоение значения printPizza не изменяет значение fn , потому что JavaScript передается/присваивается по значению. fn получает копию значения printPizza , но не получает ссылку на printPizza переменную.

5. Вы не изменяете свойство объекта, вы присваиваете его переменной. В этом разница между a = 10 и a.property = 10