JavaScript 闭包那些事

栏目: JavaScript · 发布时间: 5年前

内容简介:在计算机中,闭包指引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在。局限自定义: 在Javascript 中子函数使用了其父函数或者外层函数的变量就产生了一个闭包。这时外层变量的值能被子函数使用且外层变量在子函数未销毁之前一直被分配不会被释放。闭包的产生由于变量作用域链引起的(由

在计算机中,闭包指引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在。

局限自定义: 在Javascript 中子函数使用了其父函数或者外层函数的变量就产生了一个闭包。这时外层变量的值能被子函数使用且外层变量在子函数未销毁之前一直被分配不会被释放。

说源头说起:

闭包的产生由于变量作用域链引起的(由 词法作用域 导致)。

从JavaScript作用域说闭包:

在ES5及之前的语言规范中作用域分3种:

  • 全局作用域
  • 局部(函数作用域)
  • eval作用域。 [注意: 没有 块级作用域]

在函数中定义的变量,就属于局部作用域,且只对函数范围内其他表达式可见。 而函数内部又可以使用父函数中的变量这就是由于作用域链,当JavaScript查找与变量关联的值时,会遵循一个查找链。这个链是基于作用域的层次结构。 如下代码:

var a = "global variable"; 
( function () { 
	console.log(a); 
	var fn = function () { 
		var a = "local variable" 
		console.log(a);
	}	 
	fn(); 
})()

//输出
//global variable
//local variable
复制代码

我们在 window 全局对象下声明了变量 a ,随后调用了一个立即执行函数,其中向控制台直接打印变量a,由于立即执行函数没有声明局部变量a所以导致JavaScript向其作用域链继续查找接着就在 window 对象中找到 a 变量并打印出它的值"global variable"。接着这个立即执行函数声明了一个局部函数变量再调用它,在这个函数变量中首先声明了一个局部变量 a 然后在向控制台输出 a 得值。JavaScript在执行时由于在fn函数作用域内部查找到了变量 a 就直接使用变量 a 的值所以打印出了local variable。

值得注意的是:

window

清楚作用域的含义了吗???

那么我们刚刚说的“ 词法 “作用域又是什么。 其实词法就是指代环境:由于函数决定作用域,并且函数是一等公民可以直接用来参数传递等。那么作用域链是怎样来确定的呢: 下面的话背熟了: 作用域链是根据函数定义时候的位置确定的而不是在调用时。--这就是“词法”作用域

如果你还不懂闭包我TM。。。

栗子:chestnut::

  • [闭包的影响]对一些li绑定点击事件并打印其索引,对比2断代码不解释:
var liListlength = 3; 
for(var i=0;i<liListlength;i++){ 
	var ele=document.querySelectorAll(".test > li")[i]; 
	ele.addEventListener("click",function(){ 
		alert("index is :" + i); 
	})		 
}

var liListlength = 3; 
for(var i=0;i<liListlength;i++){ 
	var ele=document.querySelectorAll(".test > li")[i]; 
	ele.addEventListener("click",(function(i){ 
		return function(){ 
			alert("index is :" + i); 
		} 
	})(i))	 
}
复制代码
  • [闭包的妙用]模拟封装 我们可以运用闭包模拟模块的实现,即我们可以只暴露方法接口隐藏局部变量,具体如下:
var countMoudle = (function(){ 
    var _count = 0; 
    
    var plus = function(){ 
        _count++; 
    }; 
    
    var minus = function(){ 
        _count--; 
    }; 
    
    var print = function(){ 
    	console.log(_count); 
    } 
    
    return { 
        plus: plus, 
        minus: minus, 
        print: print 
    }; 
})();

countMoudle.print()  //0
countMoudle.plus()   
countMoudle.print()  //1
countMoudle.minus()
countMoudle.print()  //0
复制代码

此时我们只暴露出了方法名而没有暴露出变量属性,这时要对变量的修改只有通过接口方法调用。


以上所述就是小编给大家介绍的《JavaScript 闭包那些事》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Scrum精髓

Scrum精髓

Kenneth Rubin / 姜信宝、米全喜、左洪斌、(审校)徐毅 / 清华大学出版社 / 2014-6-1 / CNY 79.00

短短几年时间,Scrum跃升为敏捷首选方法,在全球各地得以普遍应用。针对如何用好、用巧这个看似简单的框架,本书以通俗易懂的语言、条理清晰的脉络阐述和提炼出Scrum的精髓。全书共4部分23章,阐述了七大核心概念:Scrum框架,敏捷原则,冲刺,需求和用户故事,产品列表,估算与速率,技术债;三大角色:产品负责人,ScrumMaster,开发团队以及Scrum团队构成:Scrum规划原则及四大规划活动......一起来看看 《Scrum精髓》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具