首先呢,必须搞清楚闭包这个概念:闭包其实是一个特殊的对象,他由两部分组成,一个是执行上下文(代号A),以及在该执行上下文中创建的函数(代号B),当B执行时,如果访问了A中变量对象的变量,那么闭包就产生了。
下面这个例子会产生闭包
function add(x) {
return function _add(y){
return x + y
}
}
var sum = add(2)(3)
上面这个例子毫无疑问肯定是 5
那么使用chrome浏览器单步调试一下
将断点打到 var sum = add(2)(3) 这里
- Brealpoints 表示当前打的断点是什么
- CallStack 表示当前函数调用栈
- Scope 表示当前作用域
Scope 里面的 Local 表示当前活动对象
Scope 里面的 Closure 表示闭包
图上一直点击红色箭头所指按钮表示单点调试,代码一步一步执行,等执行到return那里的时候,右侧 Scope 里会多出一个 Closure 属性,
括号内的add表示当前闭包函数是add,闭包产生的值是 x = 2
有时候调试会发现没有这个 Closure 属性,例如下面这个例子
const obj = { name: '我是需要被绑定改变this指向的对象' }
function fn()
Function.prototype.bind = function (sbbbbb) {
const bind = Symbol();
sbbbbb[bind] = this
return function () {
sbbbbb[bind]();
}
}
fn.bind(obj);
这个例子是 bind 改变 this 指向的实现方式,将断点打向 fn.bind(obj) 接着看动态图
在动画的过程中,当走到 sbbbbb[bind]() 的时候,Local 里面会多出一个 Return value: ƒ () 的属性,展开这个属性,会发现有个 [[Scopes]] 的属性,接着展开 [[Scopes]],里面有个 Closure (Function.bind) {sbbbbb: {…}, bind: Symbol()} 就表示当前产生的闭包
wavgzdsdv