美文网首页
JavaScript 执行

JavaScript 执行

作者: 前端小丸子 | 来源:发表于2019-12-11 10:52 被阅读0次

    JavaScript 执行

    一段 JavaScript 经过编译会生成两部分:执行上下文,可执行代码。
    在执行上下文中存在一个变量环境对象(Viriable Environment),保存了变量提升的内容。

    简单的变量环境对象

    VariableEnvironment:
         myname -> undefined, 
         showName ->function : {console.log(myname)
    

    JavaScript 代码先编译在执行

    showName()
    console.log(myname)
    var myname = 'hello'
    function showName() {
        console.log('函数showName被执行');
    }
    
    1. JS 引擎在环境对象中创建一个名为myname属性,并用 undefined 对其初始;
    2. JS 引擎发现同 function 定义的函数,把函数定义存储在堆(HEAP)中,并在环境对象中创建一个 showName 的属性,然后将地址指向堆中的环境位置;
    3. JS 引擎会把声明外的代码编译为字节码

    调用栈 call statck

    调用栈是用来管理函数调用关系的一种数据结构
    把这种用来管理执行上下文的栈成为执行上下文栈,又称调用栈
    console.track() 查看调用栈

    let 和 const

    作用域 scope
    作用域是指在程序中定义变量的区域,该位置决定了变量的生命周期。通俗地理解,作用域就是变量与函数的可访问范围,即作用域控制着变量和函数的可见性和生命周期。

    • 全局作用域中的对象在代码中的任何地方都能访问,其生命周期伴随着页面的生命周期
    • 函数作用域就是在函数内部定义的变量或者函数,并且定义的变量或者函数只能在函数内部被访问。函数执行结束之后,函数内部定义的变量会被销毁
      代码块内部定义的变量外部是访问不到的,代码块中的代码执行完成,代码块中定义的变量就会销毁。

    S6 之前是不支持块级作用域的,因为当初设计这门语言的时候,并没有想到 JavaScript 会火起来,所以只是按照最简单的方式来设计。没有了块级作用域,再把作用域内部的变量统一提升无疑是最快速、最简单的设计,不过这也直接导致了函数中的变量无论是在哪里声明的,在编译阶段都会被提取到执行上下文的变量环境中,所以这些变量在整个函数体内部的任何地方都是能被访问的,这也就是 JavaScript 中的变量提升。

    ES6 是如何做到既要支持变量提升的特性,又要支持块级作用域的呢?”

    • 第一步是编译并创建执行上下文,下面是我画出来的执行上下文示意图,你可以参考下:
    • 函数内部通过 var 声明的变量,在编译阶段全都被存放到变量环境里面了。
    • 通过 let 声明的变量,在编译阶段会被存放到词法环境(Lexical Environment)中
    • 在函数的作用域内部,通过 let 声明的变量并没有被存放到词法环境中。

    作用域链

    每个执行上下文的变量环境中,都包含一个外部引用,
    用来指向外部的执行上下文,我们把这个外部引用成为outer.

    词法作用域
    词法作用域是指作用域是有代码中函数声明的
    法作用域是代码阶段就决定好的,和函数是怎么调用的没有关系
    词法作用域
    词法作用域是指作用域是由代码中函数声明的位置来决定的,所以词法作用域是静态作用域。词法作用域是代码阶段就确定好的,和函数执行无关。

    闭包

    
    function foo() {
        var myName = "li"
        let test1 = 1
        const test2 = 2
        var innerBar = {
            getName:function(){
                console.log(test1)
                return myName
            },
            setName:function(newName){
                myName = newName
            }
        }
        return innerBar
    }
    var bar = foo()
    bar.setName("liyunfei")
    bar.getName()
    console.log(bar.getName())
    

    当执行到foo函数时的调用栈情况

    foo函数执行上下文 =》变量环境, 词法环境

    全局执行上下文 =》变量环境, 词法环境

    闭包是怎么回收的

    this

    执行上下文:
    变量环境、词法环境、outer、this;

    相关文章

      网友评论

          本文标题:JavaScript 执行

          本文链接:https://www.haomeiwen.com/subject/kylogctx.html