什么是javascript闭包?
创新互联致力于互联网品牌建设与网络营销,包括网站制作、网站建设、SEO优化、网络推广、整站优化营销策划推广、电子商务、移动互联网营销等。创新互联为不同类型的客户提供良好的互联网应用定制及解决方案,创新互联核心团队十多年专注互联网开发,积累了丰富的网站经验,为广大企业客户提供一站式企业网站建设服务,在网站建设行业内树立了良好口碑。
javascript允许使用内部函数,内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。
简单的javascript闭包例子:
script
function
f1(){
var
n=999;
nAdd=function(){n+=1}
function
f2(){
alert(n);
}
return
f2;
}
var
result=f1();
result();
//
999
nAdd();
result();
//
1000
/script
在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。
为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage
collection)回收。
这段代码中另一个值得注意的地方,就是"nAdd=function(){n+=1}"这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous
function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。
闭包的应用:
var
singleton
=
function
()
{
var
privateVariable;
function
privateFunction(x)
{
...privateVariable...
}
return
{
firstMethod:
function
(a,
b)
{
...privateVariable...
},
secondMethod:
function
(c)
{
...privateFunction()...
}
};
}();
这个单件通过闭包来实现。通过闭包完成了私有的成员和方法的封装。匿名主函数返回一个对象。对象包含了两个方法,方法1可以方法私有变量,方法2访问内部私有函数。需要注意的地方是匿名主函数结束的地方的'()',如果没有这个'()'就不能产生单件。因为匿名函数只能返回了唯一的对象,而且不能被其他地方调用。这个就是利用闭包产生单件的方法。
闭包的优势:
(1)不增加额外的全局变量,
(2)执行过程中所有变量都是在匿名函数内部。
闭包的缺点:
(1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
(2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public
Method),把内部变量当作它的私有属性(private
value),这时一定要小心,不要随便改变父函数内部变量的值。
本文就为大家介绍这里,如果大家对javascript闭包还是不够了解,请阅读相关文章进行补充学习,谢谢大家的阅读。
JavaScript各行代码如何理解?function foo(a,b,c){ }
var bar={ };
foo.apply(bar,[1,2,3]);
foo.call(bar,1,2,3);
function foo(a,b,c){ } // 定义一个函数
var bar={ }; // 定义一个 JSON 对象
foo.apply(bar,[1,2,3]); // 这一句的意思是在指定的作用域下执行这个函数, 第一个参数就是你指定的作用域, 也就是bar, 此时所有的操作都会在 bar 这个对象下进行
foo.call(bar,1,2,3); // 与上一句意思一样,唯一不同的是传入的参数方式不一样,上一句参数必须作为数组传入, call 方法需要把参数逐个传入
Javascript没有提供“类”这种语法结构,也就是类似Java语言里的class,不过Javascript的确有保留class这一关键字。
Javascript是面向对象语言,比Java还要彻底的面向对象。在Javascript中使用“构造器”来实现对象的类型化。构造器就是函数,惯例是首字母大写函数名来代表这是一个构造器,用new+构造器名字来创建实例对象,在构造器(及其原型属性对象)内部,this指代实例对象。
Javascript采用“原型继承”而不是“类型继承”,通过对象的原型链进行属性(方法)的查找。