[程序员每日5分钟]JS 中的闭包是什么
2017-01-17 本文已影响666人
anonymous66
Closures
闭包 是前端开发者面试必问的一个知识点。
1、什么是闭包?
2、闭包的作用是什么?
一、变量的作用域
你要学习和理解闭包 ,那么首先你要知道 JS 的作用域。
在 JS 中就只有两种:全局变量 和 局部变量。
JS 特殊之处,就在于 函数内部 可以直接读取 全局变量。
var name = 'anonymous66'
function getName(){
alert(name)
}
getName()// anonymous66
另一方面,在 函数外部 自然无法读取 函数内的局部变量。
function getName(){
var name = 'anonymous66'
}
alert(name)// 读取不到
一定要使用 var 命令。如果不用的话,你实际上声明了一个 全局变量!
function getName(){
name = 'anonymous66'
}
getName()
alert(name) // anonymous66
二、什么是闭包
我们来看一个典型的闭包
function Man() {
var name = 'anonymous66'
function getName() {
alert(name)
}
return getName
}
var man = Man()
man() // 'anonymous66'
函数getName 能够访问 函数Man 内部的变量,那么 函数getName 和 变量name 这整个环境就可以称之为� 闭包。
闭包就是能够读取其他函数内部变量的函数。
知乎有人是这样解释的:闭包就像是包子,包子每个陷(环境)都不同,就像肉包、菜包、等等。
三、闭包的作用是什么
闭包 相当于是一个拥有 “运行环境” 的函数
- 一个团队在协作开发过程中,尽量保证每个人开发的模块(函数)都有自己的“运行环境”,而不会造成全局变量污染以及模拟了命名空间开发的模式。
// 成员A负责开发A模块,里面有函数showName
var A = function () {
var name = 'A'
this.showName = function () {
console.log(name)
}
}
// 成员B负责开发B模块,里面也有函数showName
var B = function () {
var name = 'B'
this.showName = function () {
console.log(name)
}
}
// 最后项目合并的时候,调用A和B两个模块,哪怕函数名字一样也互不影响。
var a = new A()
a.showName() // 'A'
var b = new B()
b.showName() // 'B'
- 闭包通常用来创建内部变量,使得这些变量不能被外部随意修改,同时又可以通过指定的函数接口来操作。
var Man = function () {
var name = 'anonymous66'
var age = 18
this.getName = function () {
return name
}
this.getAge = function () {
return age
}
}
// 利用闭包可以给对象设置「私有属性」并利用「特权方法」访问私有属性
var man = new Man()
man.name // undefined
man.age // undefined
man.getName() // 'anonymous66'
man.getAge() // 18
- 闭包会使得函数中的变量都被保存在内存中。
function Count(){
var n = 1
this.nAdd = function () {
n += 1
}
function show() {
alert(n)
}
return show
}
var result = new Count()
result() // 1
result.nAdd()
result() // 2
为什么会这样呢?原因就在于Count是show的父函数,而show被赋给了一个Count的变量,这导致show始终在内存中,而show的存在依赖于Count,因此Count也始终在内存中,不会在调用结束后,被垃圾回收机制回收。
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,(IE 有 bug,IE 在我们使用完闭包之后,依然回收不了闭包里面引用的变量。)所以,在退出函数之前,将不使用的局部变量全部删除。
四、总结
1、闭包就是一个拥有 “运行环境” 的函数
2、解决全局变量污染,模拟命名空间
3、可以给对象设置「私有属性」并利用「特权方法」访问私有属性
4、变量都被保存在内存中
喜欢文章吗?那就点一下喜欢之后关注我把,尽量每周更新。