首先呢,我们必须搞清楚闭包这个概念:闭包其实是一个特殊的对象,他由两部分组成,一个是执行上下文(代号A),以及在该执行上下文中创建的函数(代号B),当B执行时,如果访问了A中变量对象的变量,那么闭包就产生了。
今天我们就用chrome浏览器带你断点调试理解闭包,好了直接上代码吧
下面这段代码呢?非常简单,在平时实践当中,我们很容易看到,也知道他会产生闭包,但是到底为什么呢?
// 下面这个例子会产生闭包
function add(x) {
return function _add(y){
return x+y
}
}
var sum = add(2)(3)
console.log(sum)
上面这个例子毫无疑问打印出来肯定是 5
那么我们来使用chrome浏览器单步调试一下
看到右边的单步调试了?当内部函数_add被调用执行时,访问了add函数变量对象中的x,这个时候,闭包就会产生了,这里一定要记住,函数参数变量传递给函数之后也会加到变量对象中
图上一直点击的那个上箭头表示单步调试,而左边的蓝色箭头便是断点的提示,右边的 CallStack表示当前函数调用栈,Scope表示当前作用域,Local表示当前活动对象,Closure表示闭包(在这里闭包是add函数)。
我们再来看一个例子:也是我们日常工作中会经常看到的
var name = "window"
var p = {
name: 'Ken',
getName:function() {
return function() {
return this.name;
}
}
}
var getName = p.getName()
var _name = getName.call(p)
console.log(_name)
你说上面这个例子会不会产生闭包呢?在这里我们留下一个悬念,留给读者去思考,接下来我们来看看第三个例子吧,也是很常见的哦
var name = "window"
var p = {
name: 'Ken',
getName:function() {
var self = this;
// 内部函数对变量 this 的引用
return function() {
return self.name;
}
}
}
var getName = p.getName()
var _name = getName()
console.log(_name)
同样我们也使用Chrome浏览器调试一番。
看到没有,上面这个例子是会产生闭包的,为什么呢?在一开始就讲过了,闭包其实是一个特殊的对象,他由两部分组成,一个是执行上下文(代号A),以及在该执行上下文中创建的函数(代号B),当B执行时,如果访问了A中变量对象的变量,那么闭包就产生了。
在这个例子中呢,getName()方法中定义了 var self = this, 然后return function (){return self.name},这里面的 self.name 中引用了 外部函数的 self 所以当函数调用时闭包肯定会产生,不信,你可以使用Chrome浏览器调试一番,好了今天就讲到这里吧