如何向某人解释JavaScript关闭,知道它们所构成的概念(例如功能、变量等),但不了解关闭本身?
我已经在维基百科上看到了图表的例子,但不幸的是,它没有帮助。
如何向某人解释JavaScript关闭,知道它们所构成的概念(例如功能、变量等),但不了解关闭本身?
我已经在维基百科上看到了图表的例子,但不幸的是,它没有帮助。
当前回答
MDN 解释我认为最好的:
关闭是指独立(自由)变量的函数,换句话说,关闭中定义的函数“记得”它创造的环境。
关闭总是有一个外部功能和一个内部功能. 内部功能是所有工作发生的地方,而外部功能只是保留内部功能创建的范围的环境。 这样,关闭的内部功能“记得”它创建的环境/范围。
var closure = function() {
var count = 0;
return function() {
count++;
console.log(count);
};
};
var counter = closure();
counter() // returns 1
counter() // returns 2
counter() // returns 3
在上面的代码中,计算是由外部函数(环境函数)保存的,所以每次你呼叫计算(),内部函数(工作函数)可以增加它。
其他回答
var foo = function() {
alert("Hello World!");
};
var bar = function(arg) {
return arg;
};
bar(foo)();
function add(value1, value2) {
function doAdd(operand1, operand2) {
return operand1 + operand2;
}
return doAdd(value1, value2);
}
var foo = add(1, 2);
// foo equals 3
function add(value1, value2) {
function doAdd() {
return value1 + value2;
}
return doAdd();
}
var foo = add(1, 2);
// foo equals 3
创建关闭 一个关闭是当一个内部函数从创建它的函数的外部可访问时创建的,这通常发生在一个外部函数返回一个内部函数时,当这种情况发生时,内部函数保持了一个参考到它创建的环境。
function add(value1) {
return function doAdd(value2) {
return value1 + value2;
};
}
var increment = add(1);
var foo = increment(2);
// foo equals 3
function increment(value2) {
return 1 + value2;
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Closures</title>
<meta charset="UTF-8" />
<script>
window.addEventListener("load", function() {
window.setInterval(showMessage, 1000, "some message<br />");
});
function showMessage(message) {
document.getElementById("message").innerHTML += message;
}
</script>
</head>
<body>
<span id="message"></span>
</body>
</html>
window.addEventListener("load", function() {
var showMessage = getClosure("some message<br />");
window.setInterval(showMessage, 1000);
});
function getClosure(message) {
function showMessage() {
document.getElementById("message").innerHTML += message;
}
return showMessage;
}
模拟私人数据
function Person(name) {
this._name = name;
this.getName = function() {
return this._name;
};
}
var person = new Person("Colin");
person._name = "Tom";
// person.getName() now returns "Tom"
function Person(name) {
var _name = name;
this.getName = function() {
return _name;
};
}
var person = new Person("Colin");
person._name = "Tom";
// person._name is "Tom" but person.getName() returns "Colin"
在LOPS
<!DOCTYPE html>
<html lang="en">
<head>
<title>Closures</title>
<meta charset="UTF-8" />
<script>
window.addEventListener("load", function() {
for (var i = 1; i < 4; i++) {
var button = document.getElementById("button" + i);
button.addEventListener("click", function() {
alert("Clicked button " + i);
});
}
});
</script>
</head>
<body>
<input type="button" id="button1" value="One" />
<input type="button" id="button2" value="Two" />
<input type="button" id="button3" value="Three" />
</body>
</html>
要解决这个问题,关闭必须从实际路径变量中分开,这可以通过呼叫一个新的函数来完成,这反过来创造了一个新的参考环境,下面的例子表明如何做到这一点,路径变量转移到 getHandler() 函数, getHandler() 然后返回一个独立于原来的“为”路径的关闭。
function getHandler(i) {
return function handler() {
alert("Clicked button " + i);
};
}
window.addEventListener("load", function() {
for (var i = 1; i < 4; i++) {
var button = document.getElementById("button" + i);
button.addEventListener("click", getHandler(i));
}
});
function Person(name) {
var _name = name;
this.getName = function() {
return _name;
};
this.sayHello = function() {
alert("Hello!");
};
}
function Person(name) {
var _name = name;
this.getName = function() {
return _name;
};
}
Person.prototype.sayHello = function() {
alert("Hello!");
};
要记住的事情
函数在其定义的对象/函数范围内执行,该函数可以访问在其执行期间在对象/函数中定义的变量。
写字,写字,写字,写字:P
如果该函数包含类似于呼叫回复函数,则呼叫回复函数仍在范围内;如果呼叫回复函数在母函数的即时环境中提到某些本地变量,那么当然,你会期望该变量无法访问呼叫回复函数并返回未定义。
关闭确保通过召回函数提到的任何属性都可用于该函数的使用,即使其母函数可能已经失效。
最简单、最短、最容易理解的答案:
关闭是一个代码块,每个行都可以用相同的变量名称引用相同的变量集。
如果“这”意味着与它在其他地方做什么不同,那么你知道它是两个不同的关闭。
函数 foo(x) { var tmp = 3;函数栏(y) { console.log(x + y + (++tmp)); // 会记录 16 } 栏(10); } foo(2);
函数栏,以及其与函数 foo 的语法环境的联系,是关闭。
函数 foo(x) { var tmp = 3; 返回函数 (y) { console.log(x + y + (++tmp)); // 还会记录 16 } } var bar = foo(2); bar(10); // 16 bar(10); // 17
一个关闭的最简单的例子是:
var a = 10; 函数测试() { console.log(a); // 将输出 10 console.log(b); // 将输出 6 } var b = 6; 测试();