We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
函数在被调用执行时,会创建一个当前函数的执行上下文。在该执行上下文的创建阶段,变量对象、作用域链、闭包、this指向会分别被确定。而一个JavaScript程序中一般来说会有多个函数,JavaScript引擎使用函数调用栈来管理这些函数的调用顺序。函数调用栈的调用顺序与栈数据结构一致。
断点调试工具的打开方式和常用功能见上一篇文档《浏览器开发者工具使用(以Chrome为例)》相关章节,这里不再进行补充。
在显示代码行数的地方点击,即可设置一个断点。断点设置有以下几个特点:
//demo var fn; var a=2; function f1(){ var a=4; function f2(){ console.log(a); } fn=f2; } f1(); fn();//4
这是一个很典型的闭包例子,在实际开发中,闭包不可谓不常见。但对于闭包的定义是什么,却不是一个很好回答的问题。在这里,通过浏览器的调试工具,我们至少可以知道Chrome浏览器是怎么解释闭包这一回事的。
一步一步执行,当执行到上面的例子中:
我们可以看到,在Chrome工具的理解中,由于在f1内部声明的f2函数在调用时访问了它的变量a,因此f1成为了闭包。
我们修改一下demo中的例子,来看看一个非常有意思的变化。
//demo02 var fn; var m = 20; function f1() { var a = 2; function f2(a) { console.log(a); } fn = f2; } function f3() { fn(m); } f1(); f3();
这个例子在demo01的基础上,在f2函数中传入一个参数,并打印出来。在调用时,将全局变量m传入。输出结果变为20。再使用断点调试看看作用域链。
这时我们可以发现,闭包没有了,作用域链中没有包含f1了。通过这个对比,我们可以确定闭包的形成需要两个条件。
我们继续来看看一个例子。
//demo03 function f1() { var a = 2; function f2(a) { console.log(a); } fn = f2; } function f3() { fn(m); } f1(); f3();
在这个例子中,fn只访问了f1中的a变量,因此它的闭包只有f1。
不出所料,当fn添加访问f2中的b变量的时候,它的闭包也变为了2个。
我们知道,闭包在模块中的应用也非常重要。因此,我们来一个模块的例子,也用断点工具来观察一下。
(function(){ var a=10; var b=20; var test={ m:20, add:function(x){ return a+x; }, sum:function(){ return a+b+this.m; }, mark:function(k,j){ return k+j; } } window.test=test; })(); test.add(100); test.sum(); test.mark(); var _mark=test.mark; _mark();
当add执行时,闭包为外层的自执行函数,this指向test
sum执行时,同上
mark执行时,闭包为外层的自执行函数,this指向test
_mark执行时,闭包为外层的自执行函数,this指向Window
更多的例子,大家可以自行尝试,总之,学会了使用断点调试之后,我们就能够很轻松地了解一段代码的执行过程了。这对快速定位错误,快速了解他人的代码都有非常巨大的帮助。大家一定要动手实践,把它给学会。
最后,根据以上的摸索情况,再次总结一下闭包:
断点调试是个非常有趣又实用的功能,经常使用可以提高熟练度和理解一些原理上的难题(如闭包和this指向的问题)。新手在接手新的任务的时候,可以对原有的代码进行断点调试和代码分析,可以对任务快速熟练上手。
The text was updated successfully, but these errors were encountered:
XiangLuoyang
No branches or pull requests
利用断点调试进行代码分析(以闭包为例)
参考资料
(本次主要是参考这个地址的资料,本文仅做引用分享,更加详细的信息和用例可以点进链接之后详细参考)
基础概念回顾
函数在被调用执行时,会创建一个当前函数的执行上下文。在该执行上下文的创建阶段,变量对象、作用域链、闭包、this指向会分别被确定。而一个JavaScript程序中一般来说会有多个函数,JavaScript引擎使用函数调用栈来管理这些函数的调用顺序。函数调用栈的调用顺序与栈数据结构一致。
认识断点调试工具
断点调试工具的打开方式和常用功能见上一篇文档《浏览器开发者工具使用(以Chrome为例)》相关章节,这里不再进行补充。
断点设置
在显示代码行数的地方点击,即可设置一个断点。断点设置有以下几个特点:
实例
这是一个很典型的闭包例子,在实际开发中,闭包不可谓不常见。但对于闭包的定义是什么,却不是一个很好回答的问题。在这里,通过浏览器的调试工具,我们至少可以知道Chrome浏览器是怎么解释闭包这一回事的。
一步一步执行,当执行到上面的例子中:
我们可以看到,在Chrome工具的理解中,由于在f1内部声明的f2函数在调用时访问了它的变量a,因此f1成为了闭包。
我们修改一下demo中的例子,来看看一个非常有意思的变化。
这个例子在demo01的基础上,在f2函数中传入一个参数,并打印出来。在调用时,将全局变量m传入。输出结果变为20。再使用断点调试看看作用域链。
这时我们可以发现,闭包没有了,作用域链中没有包含f1了。通过这个对比,我们可以确定闭包的形成需要两个条件。
我们继续来看看一个例子。
在这个例子中,fn只访问了f1中的a变量,因此它的闭包只有f1。
不出所料,当fn添加访问f2中的b变量的时候,它的闭包也变为了2个。
我们知道,闭包在模块中的应用也非常重要。因此,我们来一个模块的例子,也用断点工具来观察一下。
更多的例子,大家可以自行尝试,总之,学会了使用断点调试之后,我们就能够很轻松地了解一段代码的执行过程了。这对快速定位错误,快速了解他人的代码都有非常巨大的帮助。大家一定要动手实践,把它给学会。
最后,根据以上的摸索情况,再次总结一下闭包:
后记
断点调试是个非常有趣又实用的功能,经常使用可以提高熟练度和理解一些原理上的难题(如闭包和this指向的问题)。新手在接手新的任务的时候,可以对原有的代码进行断点调试和代码分析,可以对任务快速熟练上手。
The text was updated successfully, but these errors were encountered: