javascript的关闭
前言:介绍性的文章。有Javascript对象,几个非常重要的语言特征的原型,和关闭。关闭是程序员使用传统的静态语言C / C++的一种新的语言特征,本文将以一个例子来介绍Javascript闭包的语言特点,并结合一点ECMAscript语言规范,使读者能够深入理解闭包。注:本文是一篇介绍性文章,示例材料设置在网络上。如果您是高手,欢迎您对本文提出技术建议和建议。本文是关于Javascript的,不想做语言对比。如果你想Javascript,请绕道而行。
什么是壁橱
闭包是闭包的闭包,闭包是静态语言不具备的一个新特性,但是闭包并不是那么复杂以至于可以理解的。简言之,关闭是:
闭包是函数的一组局部变量,但是这些局部变量在函数返回后仍将继续存在。
闭包是函数返回后堆栈不会释放。我们还可以理解,这些函数堆栈不是在堆栈上分配的,而是在堆上分配的。
当函数中定义了另一个函数时就会生成闭包。
上面的第二个定义是先补充描述提取主谓宾-第一个定义的关闭是局部变量设置的功能。它仅仅是局部变量,可以在函数返回访问。(这是不是一个正式的定义,但这个定义应该是更有利于你的关闭的理解)。
作为一个局部变量,它可以访问的代码的功能,它不同于静态的语言。在关闭不同的是,局部变量可以通过函数外的代码后执行功能。这意味着一个函数必须返回一个引用到关闭或转让引用一个外部变量,因此在封闭的局部变量可以由外部代码访问。当然,包含该参考实体应该是一个对象,因为所有的Javascript的其余部分是除了基本类型的对象。不幸的是,ECMAscript并没有提供相关的成员和方法在关闭访问局部变量。但在ECMAscript,内府功能,这是函数对象的定义,是一个局部变量,可以直接访问外部函数。通过这个机制,我们可以通过以下方式完成对闭包的访问。
复制代码代码如下所示:
函数问候语(姓名){
var text =你好+姓名; / /局部变量
每调用一次,并返回到内部函数,对象调用方。
返回函数(){警报(文本);}
}
VaR方法sayHello =问候(关闭);
(打招呼) / /通过访问局部变量的文本关闭
上述代码的执行结果是你好关闭,因为sayHello()函数仍然可以访问定义在问候功能后已执行的局部变量文本。
好的,这是闭包在图例中的作用。闭包在javascript中有许多应用场景和模式,如单例、构造函数等。这些Javascript模式与闭包的使用是分不开的。
ECMAscript封闭模型
如何在年底实现ECMAscript关闭人们想知道更多关于它可以为研究ECMAscript规范,我只是做了一个简单的解释,与内容来源于网络。
ECMAscript脚本函数运行时,每个函数会执行上下文情景(执行上下文),其中包含三个部分的执行上下文情景。
语法环境(的lexicalenvironment)
环境变量(该变量环境)
这种结合
第三这种绑定是不相关的关闭和不在本文讨论。语法环境用于解析的函数执行过程中使用的标识符的变量,我们可以想象的语法环境为对象,其中包含两个重要组成部分,环境记录和外部参考。环境记录包含本地和参数变量包含的函数内部声明,和外部参考点到外部函数对象的上下文中执行的场景。这个参考价值在全球范围内的情况下是无效的。这样的数据结构,形成一个单向链表,每个参考点,外层的上下文场景。
例如,关闭模型上面的例子应该是这样的,sayHello函数是在底部,上层是函数的问候,最外层是全球场景。下图:所以当打招呼时,sayHello将文本的值找到当地的语境,所以你好,关闭对话框屏幕显示环境变量(该变量环境)的环境类似的基本语法的作用,规范文档的具体区别请参见ECMAscript。
关闭
我对Javascript闭包和闭包是如何在Javascript中实现的有一个大致的了解,现在我们通过一些例子帮助您进一步理解闭包。有5个样品。这个例子是来自Javascript闭包的傻瓜(镜像)。1闭包中的局部变量是引用而不是副本。
复制代码代码如下所示:
功能say667(){
本地变量,该变量最终在闭包中结束
var = 666;
无功sayalert =函数(){ alert(努姆);}
数字+;
返回sayalert;
}
无功sayalert = say667();
SayAlert()
所以结果的执行应该是667而不是666。
示例2:多个函数绑定到同一闭包,因为它们是在同一个函数中定义的。
复制代码代码如下所示:
功能setupsomeglobals(){
本地变量,该变量最终在闭包中结束
var = 666;
将函数的一些引用存储为全局变量
galertnumber =函数(){ alert(努姆);}
gincreasenumber =函数(){数+ +;}
gsetnumber =函数(x){ Num = x;}
}
(setupsomeglobals) / /分配;三全局变量
galertnumber(); / / 666
GIncreaseNumber();
galertnumber(667); / /
gsetnumber(12); / /
galertnumber(); / / 12
示例3:当函数在循环中分配时,这些函数绑定相同的闭包。
复制代码代码如下所示:
功能buildlist(列表){
var result = { };
对于(var i = 0;i < list.length;i++){
VAR项= 'Item' +表{我};
result.push(函数(){ alert(项目++表{我})});
}
返回结果;
}
功能testlist(){
无功fnlist = buildlist({1,2,3});
J只是为了防止使用混乱-可以使用我
对于(var j = 0;J < fnlist.length;j++){
fnlist {,}();
}
}
对testlist执行是弹出窗口Item3定义结果的三倍,因为三的功能绑定同一关闭,和项目的价值是最后的结果,但是当我被淘汰出局,我的值是4,所以{ 4 }定义列表的结果..
例4:外部函数的所有局部变量都在闭包中,即使变量在内部函数定义之后声明。
复制代码代码如下所示:
功能sayalice(){
无功sayalert =函数(){ alert(爱丽丝);}
本地变量,该变量最终在闭包中结束
Var Alice:你好爱丽丝;
返回sayalert;
}
无功helloalice = sayalice();
helloalice();
执行的结果是弹出窗口你好爱丽丝,甚至在局部变量是在函数声明的局部变量sayalert,仍然可以访问。
例5:每次调用函数调用时都会创建一个新闭包。
复制代码代码如下所示:
功能newclosure(somenum,someref){
本地变量,这些变量最终会在闭包中结束
Num = somenum VaR;
VaR分析= {1,2,3};
VaR作为someref;
返回函数(x){
数字= x;
AnArray.push(努姆);
警报('num:+数字+ +)
' 一个+ anarray.tostring()+
' ref.somevar + ref.somevar);
}
}
closure1 = newclosure(40,{ somevar:'closure 1 });
closure2 = newclosure(1000,{ somevar:'closure 2 });
closure1(5); / /数:45一1,2,3,45 } {编号:'somevar closure1
closure2(- 10); / /数:990一1,23990 } {编号:'somevar closure2
应用闭合
单件单件:
复制代码代码如下所示:
var =函数(){()
无功privatevariable;
函数功能产生于(x){
…privatevariable…
}
返回{
制法:功能(A,B){
…privatevariable…
},
方法:功能(C){
…功能产生于()…
}
};
(});
这张是通过关闭。私有成员的封装方法是完成关闭。匿名主函数返回一个对象,该对象包含两个方法,方法1可以是私有变量和方法2访问内部私有函数。它需要注意到的是,在匿名的主函数结束这个地方是'()',如果没有'()'不能产生一个单一的一块。因为匿名函数只能返回唯一的对象,而不能称之为别处。这是用一个衣柜生产单件的方式。