首页 技术 正文
技术 2022年11月14日
0 收藏 936 点赞 3,483 浏览 1831 个字

在chrome的开发者工具中,通过断点调试,我们能够非常方便的一步一步的观察JavaScript的执行过程,直观感知函数调用栈,作用域链,变量对象,闭包,this等关键信息的变化。因此,断点调试对于快速定位代码错误,快速了解代码的执行过程有着非常重要的作用,这也是我们前端开发者必不可少的一个高级技能。

函数在被调用执行时,会创建一个当前函数的执行上下文。在该执行上下文的创建阶段,变量对象、作用域链、闭包、this指向会分别被确定。JavaScript程序中一般有多个函数,JavaScript引擎使用函数调用栈来管理这些函数的调用顺序,函数调用栈的调用顺序与栈数据结构一致。

代码段1

var fn;function funcOut(){    var a = 2;    function funcIn(){        console.log(a);    }    fn = funcIn;}function funcTest(){    fn();}funcOut();funcTest();

在funcOut()处设置断点,刷新页面;

点击step into,注意观察下方call stack与scope的变化,以及函数执行位置的变化。

在chrome开发者工具中观察函数调用栈、作用域链、闭包

我们可以看到,在funcOut内部声明的funcIn函数在调用时访问了它的变量a,因此funcOut成为了闭包。

代码段2

var fn;var n = 20;function funcOut(){    var a = 2;    function funcIn(a){        console.log(a);    }    fn = funcIn;}function funcTest(){    fn(n);}funcOut();funcTest();

闭包没了,作用域链中没有包含funcOut了。

在chrome开发者工具中观察函数调用栈、作用域链、闭包

代码段3

function funcOut() {    var a = 2;    return function funcIn() {        var b = 20;        return function fn() {            console.log(a);        }    }}var funcIn = funcOut();var fn = funcIn();fn();

fn只访问了funcOut中的a变量,因此它的闭包只有funcOut。

在chrome开发者工具中观察函数调用栈、作用域链、闭包

代码段4

function funcOut() {    var a = 2;    return function funcIn() {        var b = 20;        return function fn() {            console.log(a,b);        }    }}var funcIn = funcOut();var fn = funcIn();fn();//2 20

这个时候,闭包变成了两个。分别是funcIn,funcOut。

在chrome开发者工具中观察函数调用栈、作用域链、闭包

代码段5

//闭包在模块中的应用(function() {    var a = 10;    var b = 20;    var myObj = {        c: 20,        sum1: function(x) {            return a + x;        },        sum2: function() {            return a + b + this.c;        },        sum3: function(k, j) {            return k + j;        }    }    window.myObj = myObj;})();myObj.sum1(100);myObj.sum2();myObj.sum3();var funcTest = myObj.sum3;funcTest();

sum1执行时,闭包为外层的自执行函数,this指向myObj。

在chrome开发者工具中观察函数调用栈、作用域链、闭包

sum2执行时,闭包为外层的自执行函数,this指向myObj。

在chrome开发者工具中观察函数调用栈、作用域链、闭包

sum3执行时,闭包为外层的自执行函数,this指向myObj。

在chrome开发者工具中观察函数调用栈、作用域链、闭包

funcTest执行时,闭包为外层的自执行函数,this指向Window。

在chrome开发者工具中观察函数调用栈、作用域链、闭包

这里的this指向显示为Object或者Window,大写开头,他们表示的是实例的构造函数,实际上this是指向的具体实例。

代码段6

var a = 10;var obj = {    a: 20}function fn() {    console.log(this.a);}fn.call(obj); 

在chrome开发者工具中观察函数调用栈、作用域链、闭包

代码段7

function funcOut() {  var a = 10;  function funcIn1() {      return a;  }  function funcIn2() {      return 10;  }  funcIn2();}funcOut();

在chrome开发者工具中观察函数调用栈、作用域链、闭包

这个例子,和其他例子不太一样。虽然funcIn2并没有访问到funcOut的变量,但是funcOut执行时仍然变成了闭包。而当我将funcIn1的声明去掉时,闭包便不会出现了。我暂时也不知道应该如何解释这种情况。只能大概知道与funcIn1有关,可能浏览器在实现时就认为只要存在访问上层作用域的可能性,就会被当成一个闭包吧。

在chrome开发者工具中观察函数调用栈、作用域链、闭包

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,085
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,560
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,409
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,182
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,819
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,902