javascript闭包学习笔记
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript闭包学习笔记相关的知识,希望对你有一定的参考价值。
1.闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的常见方式,就是在一个函数内部创建另一个函数。
2.什么情况下会发生闭包?
当在函数内部定义了其他函数时,就创建了闭包。
3.什么场景下需要?
如果一个函数需要在其父级函数返回后留住对父级作用域的链接的话,就必须要为此建立一个闭包。
4.闭包闭了谁?
在函数内部创建一个函数时,在外部调用这个内部函数,虽然调用发生在全局域,但是内部函数还是会访问当初被定义的时刻的那个原始域,这个域就是它的闭包,闭包了需要访问的变量。
5.闭包的优点是什么,缺点是什么?
闭包的优点:可以把局部变量驻留在内存中,给要访问的函数使用,这样就可以避免使用全局变量。闭包的缺点:闭包会比其他函数更多的占用内存,过度使用闭包,可能导致内存占用过多,可能会导致内存泄露。
6.做为局部变量都可以被函数内的代码访问,这个和静态语言是没有差别。闭包的差别在于局部变变量可以在函数执行结束后仍然被函数外的代码访问.
7.闭包中this的使用
一般情况下,this对象是在运行时基于函数的执行环境绑定的,在全局函数中,this等于window,而当函数被作为某个对象的方法调用时,this等于那个对象。但是,注意!匿名函数的执行环境具有全局性,因此此时的this对象指向window.此外,每个函数在被调用时都会自动取得两个特殊变量:this和arguments.而内部函数在搜索这两个变量时,只会搜索到其活动对象为止
(1):
var name = "The Window";var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()());
object.getNameFunc()执行完后,返回匿名函数function(){return this.name;}的引用,object.getNameFunc()(),执行匿名函数,此时这个执行环境是在全局作用域下,而它的活动对象为全局变量的name=”The Window”,因此,this.name返回The Window.
(2)
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ var that = this; return function(){ return that.name; }; } }; alert(object.getNameFunc()());
此函数的修改是:在定义匿名函数之前,把this对象赋值给了一个名叫that的变量,因此定义闭包后,即使函数返回后,that也仍然引用着object,所以调用object.getNameFunc()(),返回“My Object”。
8.使用匿名函数,可以减少闭包占用内存的问题。在匿名函数中定义的任何变量,都会在执行结束时被销毁。
9.使用闭包的例子分析:
(1)
function f(){ var b = "bb"; return function(){ return b; } } var n = f(); n();//bb
当函数f()执行完后,返回匿名函数的引用,此时f()的执行环境中的变量没有被销毁,因为被外部的全局变量引用着,接着,调用匿名函数,此时匿名函数根据查找自己作用域链中的活动对象,没有变量b,继续向上一级作用域链查找,在父函数中找到变量b,并将其返回。闭包的作用,使得外部函数n(),可以访问到f()内部的变量。
(2)
var n; function f(){ var b= "bbb"; n = function(){ return b; } } f(); n();//bbb
当调用f()函数时,全局变量n被赋值了内部函数,当f()函数调用完,f的中的变量仍然在内存中,没有被销毁,由于内部函数被外部变量引用着,间接等于f也被引用着,一次,当执行到n()这个函数时,n()函数首先在作用域链中找当前的活动变量,找不到b在向上一级的父函数的变量中找,找到了则返回。这也是闭包的一种应用。
(3)
function f(arg){ var n = function(){ return arg; }; arg++; return n; } var m = f(123); m();//124
当执行f(123)时,arg自增1,函数返回内部函数的引用赋值给m,f()函数执行完后,同样它里面的变量没有被销毁,因为被变量所引用着,因此调用m(),就执行引用的那个函数(即就是闭包)返回变量arg的值124
(4)
function fn() {
var a = 0;
function f() {
console.log(a++);
}
return f;
}
var b = fn();
b(); // 0
b(); // 1
b(); // 2
和上面的那个例子,类似。函数所绑定的是作用域本身,而不是该作用域中的变量或变量当前所返回的值。
(5)
var result = new Array();
function createFunction(){
for(var i=0;i<10;i++){
result[i] = function(num){
return function(){
return num;
};
}(i);
}
return result;
}
createFunction();
for(var i=0;i<result.length;i++){
alert(result[i]());
}
当createFunction()执行时,内部定义了一个自执行的匿名函数,执行的结果返回给result[],同样函数返回这个数组,当在外部调用内部的匿名函数时,传入变量i,由于函数参数是按值传递的,所以就会将变量i当前的值复制给num,则在这个匿名函数内部,又创建并返回了一个访问num的闭包 ,这样result数组中的每个函数都有自己num变量的一个副本,因此就可以返回各自不同的值。
总结:刚开始学习闭包,对概念和简单例子做了分析总结,在后期的学习中通过实践,继续对闭包这一概念进行更加深刻的理解学习。
本文出自 “梦想需要坚持” 博客,请务必保留此出处http://xiyin001.blog.51cto.com/9831864/1774942
以上是关于javascript闭包学习笔记的主要内容,如果未能解决你的问题,请参考以下文章