在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的变化,以及函数执行位置的变化。

我们可以看到,在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了。

代码段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。

代码段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。

代码段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。

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

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

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

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

代码段6

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

代码段7

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

funcOut();

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

在chrome开发者工具中观察函数调用栈、作用域链、闭包的更多相关文章

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

    在chrome开发者工具中观察函数调用栈.作用域链与闭包 在chrome的开发者工具中,通过断点调试,我们能够非常方便的一步一步的观察JavaScript的执行过程,直观感知函数调用栈,作用域链,变量 ...

  2. 前端基础进阶(六):在chrome开发者工具中观察函数调用栈、作用域链与闭包

    在前端开发中,有一个非常重要的技能,叫做断点调试. 在chrome的开发者工具中,通过断点调试,我们能够非常方便的一步一步的观察JavaScript的执行过程,直观感知函数调用栈,作用域链,变量对象, ...

  3. 【译】在 Chrome 开发者工具中调试 node.js

    原文链接 : Debugging Node.js in Chrome DevTools 原文作者 : MATT DESLAURIERS 译文出自 : 掘金翻译计划 译文链接 : https://git ...

  4. 使用chrome开发者工具中的network面板测量网站网络性能

    前面的话 Chrome 开发者工具是一套内置于Google Chrome中的Web开发和调试工具,可用来对网站进行迭代.调试和分析.使用 Network 面板测量网站网络性能.本文将详细介绍chrom ...

  5. 在 Chrome 开发者工具中调试 node.js

    命令行工具 devtool ,它可以在 Chrome 的开发者工具中运行 Node.js 程序. 下面的记录显示了在一个 HTTP 服务器中设置断点的情况. 该工具基于 Electron 将 Node ...

  6. Chrome 开发者工具中的命令菜单

    单 大家对命令菜单(Command Menu)应该都不陌生.目前主流的编辑器中都内置了对该功能的支持.在 Sublime Text 和 Visual Studio Code 中你都可以通过快捷键 Ct ...

  7. Chrome开发者工具中Elements(元素)断点的用途

    SAP Engagement Center UI的这个按钮会每秒钟刷新一次,显示页面已经打开了多长时间. 需求:需要找到哪行JavaScript代码不断刷新的按钮文字. 按照经验判断,这个文字肯定是一 ...

  8. 使用chrome开发者工具中的performance面板解决性能瓶颈

    前面的话 使用Chrome DevTools的performance面板可以记录和分析页面在运行时的所有活动.本文将详细介绍如何使用performance面板解决性能瓶颈 准备 [匿名模式] 匿名模式 ...

  9. 使用 Chrome 开发者工具进行 JavaScript 问题定位与调试

    转自:https://www.ibm.com/developerworks/cn/web/1410_wangcy_chromejs/ 引言 Google Chrome 是由 Goole 公司开发的一款 ...

随机推荐

  1. c++刷题(18/100)树

    题目1:二叉搜索树的第k个节点 给定一颗二叉搜索树,请找出其中的第k小的结点.例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4. 思路:因为是二叉搜索树 ...

  2. Linux基础操作命令-打包压缩

    将用户信息数据库文件和组信息数据库文件纵向合并为一个文件/1.txt(覆盖) 将用户信息数据库文件和用户密码数据库文件纵向合并为一个文件/2.txt(追加) 将/1.txt./2.txt两个文件打包为 ...

  3. http Get和Post请求方式

      string postURL ="http://xxxxx.ashx"; List<string> paramName = new List<string&g ...

  4. [转]caffe中solver.prototxt参数说明

    https://www.cnblogs.com/denny402/p/5074049.html solver算是caffe的核心的核心,它协调着整个模型的运作.caffe程序运行必带的一个参数就是so ...

  5. Python——脚本(calculator)

    <Python基础教程>(第二版) P123 书中原代码如下: class Calculator: def calculator(self,expression): self.value ...

  6. go 流程控制

    if else 语句 基本语法 if condition { //do something } if condition { //do something } else if condition { ...

  7. Python Challenge 第 2 关攻略:ocr

    text="那一大推乱码" 方案1 from collections import Counter print(Counter(text)) 方案2 import string & ...

  8. 01.Web基础和HTML初始

    1.1 上网就是请求数据 我们先不直接解决这个问题,我们做一个小实验.我们每个人的电脑里面,都有一个神秘的文件夹: C:\Users\Weiheng\AppData\Local\Microsoft\W ...

  9. go语言项目汇总

    Horst Rutter edited this page 7 days ago · 529 revisions Indexes and search engines These sites prov ...

  10. Mat结构

    主要是记录一下大牛的博客,再次感谢这些无私的博主. 这篇博客http://blog.csdn.net/yang_xian521/article/details/7107786中,我觉得要注意的是Mat ...