如何向某人解释JavaScript关闭,知道它们所构成的概念(例如功能、变量等),但不了解关闭本身?
我已经在维基百科上看到了图表的例子,但不幸的是,它没有帮助。
如何向某人解释JavaScript关闭,知道它们所构成的概念(例如功能、变量等),但不了解关闭本身?
我已经在维基百科上看到了图表的例子,但不幸的是,它没有帮助。
当前回答
关闭是一种内部函数,可以访问外部(关闭)函数的变量 - 范围链. 关闭有三个范围链:它可以访问自己的范围(在曲线手臂之间定义的变量),它可以访问外部函数的变量,并且可以访问全球变量。
function showName(firstName, lastName) {
var nameIntro = "Your name is ";
// this inner function has access to the outer function's variables, including the parameter
function makeFullName() {
return nameIntro + firstName + " " + lastName;
}
return makeFullName();
}
console.log(showName("Michael", "Jackson")); // Your name is Michael Jackson
此外,这是一个经典的关闭方式在jQuery,每个JavaScript和jQuery开发人员使用它很多:
$(function() {
var selections = [];
$(".niners").click(function() { // this closure has access to the selections variable
selections.push(this.prop("name")); // update the selections variable in the outer function's scope
});
});
实用关闭
//javascript function makeSizer(size) { return function() { document.body.style.fontSize = size + 'px'; } var size12 = makeSizer(12); var size14 = makeSizer(14); var size16 = makeSizer(16); document.getElementById('size-12').onclick = size12; document.getElementById('size-14').onclick = size14; document.getElementById('size-16').onclick = size16; /*css*/ body {字体
其他回答
关闭仅仅是当一个函数进入其外部范围后,即使该范围的函数完成执行。
function multiplier(n) {
function multiply(x) {
return n*x;
}
return mutliply;
}
var 10xmultiplier = multiplier(10);
var x = 10xmultiplier(5); // x= 50
我们可以看到,即使复合器完成执行后,内部函数复合器仍然可以访问这个例子中的 x 的值,即 10。
一个非常常见的使用关闭是流动(上面的同样的例子),在那里我们逐步用参数来完善我们的功能,而不是同时提供所有论点。
我们可以实现这一点,因为JavaScript(除了原型OOP之外)允许以功能的方式编程,在那里更高的命令功能可以采取其他功能作为论点(分类功能)。
我强烈建议你阅读这本书由Kyle Simpson: 2 一部分的书系列是专门关闭,它被称为范围和关闭。
关闭是一个代码块,符合三个标准:
它可以作为一个值进行转换,并在需要时由任何拥有这个值的人执行,当时它可以从它创建的背景中提到变量(即它关闭于变量访问,在“关闭”这个词的数学意义上)。
(“关闭”这个词实际上有一个不准确的含义,有些人不认为标准1是定义的一部分。
关闭是功能语言的支柱,但它们也存在于许多其他语言(例如,Java的匿名内部课堂)。你可以用它们做一些酷的事情:它们允许偏离的执行和一些优雅的风格技巧。
由: Paul Cantrell, @ http://innig.net/software/ruby/closures-in-ruby
考虑到以下功能
function person(name, age){
var name = name;
var age = age;
function introduce(){
alert("My name is "+name+", and I'm "+age);
}
return introduce;
}
var a = person("Jack",12);
var b = person("Matt",14);
每次函数人被称为一个新的关闭创建,而变量 a 和 b 具有相同的输入函数,它与不同的关闭有关,而这个关闭仍然存在,即使函数人完成执行后。
此分類上一篇
a(); //My name is Jack, and I'm 12
b(); //My name is Matt, and I'm 14
一个抽象的封闭可以代表到这样的东西:
closure a = {
name: "Jack",
age: 12,
call: function introduce(){
alert("My name is "+name+", and I'm "+age);
}
}
closure b = {
name: "Matt",
age: 14,
call: function introduce(){
alert("My name is "+name+", and I'm "+age);
}
}
假设你知道一个班级在另一个语言是如何工作的,我会做一个类似。
想想像
JavaScript 作为构建器的本地变量作为例子属性这些属性是私人内部功能作为例子方法
每一天都有一个功能被称为
将创建一个包含所有本地变量的新对象,该对象的方法将访问该对象的“属性”。
这个过程由两个步骤组成:
此分類上一篇
函数可以相互内置,形成一连锁的LexicalEnvironments,也可以称为范围链。
此分類上一篇
此分類上一篇
正如我们所看到的, this.say 是用户对象中的属性,因此在用户完成后,它仍然活着。
如果你记得,当 this.say 创建时,它(就像每个函数一样)得到一个内部参考 this.say 到当前的 LexicalEnvironment. 因此,当前用户执行的 LexicalEnvironment 保持在记忆中。
内部函数保留对外的LexicalEnvironment的参考,内部函数可以随时从中访问变量,即使外部函数完成,浏览器保留LexicalEnvironment及其所有属性(变量)在记忆中,直到有一个内部函数引用它。
这就是所谓的关闭。
函数和函数的外部范围(语法环境)的参考
函数 汽车(制造商,模型,年,颜色) { 返回 { 到String() { 返回 `${ 制造商} ${ 模型} (${ 年}, ${ 颜色})` } } 组车 = 新车(‘Aston Martin’,‘V8 Vantage’,‘2012’,‘Quantum Silver’) console.log(car.toString())
事件导向的编程
在下面的例子中,所有实施细节都隐藏在即时执行的函数表达式内。 函数标记和 toString 接近私人状态和函数他们需要完成工作。 关闭已使我们能够模块化和包容我们的代码。
例子1
这个例子表明,本地变量在关闭中没有复制:关闭保持了对原始变量的参考。
左边