您的位置:首页 > Web前端 > JavaScript

javascript执行上下文、变量对象实例分析

2020-04-26 07:05 106 查看

本文实例讲述了javascript执行上下文、变量对象。分享给大家供大家参考,具体如下:

突然看到一篇远在2010年的老文,作者以章节的形式向我们介绍了ECMA-262-3的部分内容,主要涉及到执行上下文、变量对象、作用域、this等语言细节。内容短小而精悍,文风直白而严谨,读完有酣畅淋漓、醍醐灌顶之感,强烈推荐!!!

原文链接:这里

本想翻译成文,原来早已有人做了,这里。真生不逢时,何其遗憾啊!

做个笔记,聊慰我心。

执行上下文 ExecutionContext

每当控制器(control)转换到ECMAScript可执行代码时,都会创建并进入到一个可执行上下文。

一段简短的句子,却包含着丰富的内容:

  • 控制器:即js引擎
  • 转换:从一段可执行代码跳转到另一段可执行代码
  • 可执行代码:全局代码、函数代码、eval代码(分别对应三种作用域)
  • 执行上下文:是一个抽象的概念,ECMA-262标准用这个概念同可执行代码(executable code)概念进行区分

执行上下文在逻辑上组成一个堆栈。堆栈底部永远都是全局上下文(global context),堆栈顶部是当前/活动的执行上下文(activeExecutionContext)。堆栈在EC类型的变量(various kingds of EC)被推入或弹出的同时被修改。

例如,我们可以定义一个数组来模拟执行上下文堆栈:

ECStack = [
globalContext,
<foo> functionContext
]

变量对象 VariableObject

变量对象(VO)作为执行上下文的一个属性存在,它存储下列内容:

  • 所有变量声明 (var, VariableDeclaration) VO的一个属性,这个属性由变量名称和undefined值组成;如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性。
  • 函数声明 (FunctionDeclaration, 缩写为FD)
      VO的一个属性,这个属性由一个函数对象(function-object)的名称和值组成;如果变量对象已经存在相同名称的属性,则完全替换这个属性。
  • 以及函数的形参
      VO的一个属性,这个属性由一个形式参数的名称和值组成;如果没有对应传递实际参数,那么这个属性就由形式参数的名称和undefined值组成;
    VO = {
    // context data (var, FD, function arguments)
    }

    当我们声明一个变量或一个函数的时候,同时还用变量的名称和值在VO里创建了一个新的属性。
    例如:

    var m = 30;
    function test(a,b) {
    var c = 20
    function d() {}
    var e = function _e() {};
    }
    test(10)

    当进入“test”函数的上下文时(传递参数10),AO如下:

    AO(test) = {
    a: 10,
    b: undefined,
    c: undefined,
    d: <reference to FunctionDeclaration "d">
    e: undefined
    };

    test执行到最后时,对应此刻上下文堆栈:

    ECStack = [
    globalContext: {
    VO: {
    m: 30,
    test:
    }
    },
    test functionContext: {
    VO: {
    a: 10,
    b: undefined,
    c: 20,
    d: <reference to FunctionDeclaration "d">,
    e: <reference to FunctionDeclaration "_e">
    }
    }
    ]

    关于变量

    通常,各类文章和JavaScript相关的书籍都声称:“不管是使用var关键字(在全局上下文)还是不使用var关键字(在任何地方),都可以声明一个变量”。请记住,这绝对是谣传:任何时候,变量只能通过使用var关键字才能声明。

    让我们通过下面的实例看看具体的区别吧:

    alert(a); // undefined
    alert(b); // "b" is not defined
    
    b = 10;
    var a = 20;

    所有根源仍然是VO和它的修改阶段(进入上下文阶段和执行代码阶段):

    VO = {
    a: undefined
    };

    我们可以看到,因为“b”不是一个变量,所以在这个阶段根本就没有“b”,“b”将只在执行代码阶段才会出现(但是在我们这个例子里,还没有到那就已经出错了)。

    让我们改变一下例子代码:

    alert(a); // undefined, we know why
    
    b = 10;
    alert(b); // 10, created at code execution
    
    var a = 20;
    alert(a); // 20, modified at code execution

    关于变量,还有一个重要的知识点。变量相对于简单属性来说,变量有一个特性(attribute):{DontDelete},这个特性的含义就是不同通过delete操作符直接删除变量属性。

    a = 10;
    alert(window.a); // 10
    
    alert(delete a); // true
    
    alert(window.a); // undefined
    
    var b = 20;
    alert(window.b); // 20
    
    alert(delete b); // false
    
    alert(window.b); // still 20

    2018-8-2-再看执行上下文、变量对象

    感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。

    更多关于JavaScript相关内容可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结

    希望本文所述对大家JavaScript程序设计有所帮助。

    您可能感兴趣的文章:

  • 内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    相关文章推荐