我正在尝试找出闭包并创建了这个简单的示例,您可以使用名称调用函数greet,在第一次调用之后,greeting应该包含先前给定的名称。
所以,如果你打电话问候('安德鲁')并问候('约瑟夫')我希望在控制台上看到:
Hello Andrew
Hello Andrew, Joseph
这是我的代码: https://codepen.io/anon/pen/pVpBdy
let greet = function(name) {
let greeting = 'Hello ';
let updateGreet = function() {
greeting = greeting + ', ' + name;
}
let printGreet = function() {
console.log(greeting + name);
updateGreet();
}
return printGreet();
}
greet('Andrew');
greet('Joseph');
我看到的结果是:
Hello Andrew
Hello Joseph
每当我打电话问候()时,问候语都会重新初始化,我不明白为什么。
请帮助我理解这一点。
答案 0 :(得分:2)
您当前的greet
可以调用创建一个自包含的对象 - 对象然后存储这些名称。每当您当前致电greet
时,您都会创建一个单独的greeting
变量,并将其封装在不同的对象中。
最简单的方法是立即执行该函数,以便对greet
的所有调用都引用同一个对象。
您还应该将name
变量传递给updateGreet
:
const greet = (() => {
let greeting = 'Hello';
const updateGreet = function(name) {
greeting = greeting + ', ' + name;
}
const printGreet = function(name) {
console.log(greeting + ', ' + name);
updateGreet(name);
}
return printGreet;
})();
greet('Andrew');
greet('Joseph');
greet('Bob');

每当您声明一个不会改变其引用的变量时,请确保使用const
- 这样可以让您更容易理解代码(无论是您还是其他人)。
答案 1 :(得分:0)
变量greeting
绑定到函数greet
的范围。因此,每次拨打greet()
时,都会使用let greeting = 'Hello ';
重新初始化问候变量
要获得所需的结果,您可以将let greeting = 'Hello '
移到greet
的范围之外,以便它保持不变。
let greeting = 'Hello ';
let greet = function(name) {
let updateGreet = function() {
greeting = greeting + ', ' + name;
}
let printGreet = function() {
console.log(greeting + name);
updateGreet();
}
return printGreet();
}
greet('Andrew');
greet('Joseph');

答案 2 :(得分:0)
我将假设您不太关心获取特定输出,但您关心理解这个概念。因此我简化了你的例子:
$statement = $connection->prepare("
INSERT INTO students (name_student,students,specialization,phone_num,paid,chair,group_id)
VALUES (:name_student,:students,:specialization,:phone_num,:paid,:chair,:group_id)
");
$result = $statement->execute(
array(
':name_student' => $_POST["name_student"],
':students' => $_POST["students"],
':specialization' => $_POST["specialization"],
':phone_num' => $_POST["phone_num"],
':chair' => "1",
':paid' => $_POST["paid"],
':group_id' => $_POST['group_id']
)
);
这里发生的是当你第一次调用function greet (greeting) {
return function person (name) {
console.log(greeting + ',' + name)
}
}
helloGreeting = greet('hello')
helloGreeting('andrew') // 'hello, andrew'
helloGreeting('joseph') // 'hello, joseph'
时,函数返回一个闭包 - greet
。闭包是在另一个函数内声明的函数,并且由于在该函数内声明,它可以访问外部函数中定义的任何内容。
因此,在调用person
之后,js返回greet('hello')
函数,并且此函数可以访问先前定义的person
变量。
特别是,函数person的执行上下文包含变量greeting。您可以将执行上下文视为一个框,并且每次通过调用greeting
运行person
时,此框还包含定义为hello的变量helloGreeting
。
这样的美妙之处在于,现在您还可以定义其他问候语。
greeting
这使得可以通过组合多个函数来构造真正可重用的代码。使代码模块化的一种非常好的方法!
答案 3 :(得分:0)
没有观察到闭包,因为greet
函数不返回函数,而是函数调用,导致值undefined
。要观察闭包,外部函数可以作为IIFE调用,并且应该返回存储在变量printGreet
中的函数greet
。现在greet
引用了printGreet
函数,它仍然保持与它的词汇环境的连接。
let greet = (function() {
let greeting = 'Hello ';
let updateGreet = function(name) {
greeting = greeting + ', ' + name;
}
let printGreet = function(name) {
console.log(greeting + ', '+ name);
updateGreet(name);
}
return printGreet;
}());
greet('Andrew');
greet('Joseph');