• “预编译”


    “预编译”

    我的老师在和我讲相关知识点前和我说过这么一个笑话:

    面试时我因为这么一个问题挂了

    var a = 100
    function foo(){
        console.log(a)
    }
    foo()
     

    问:为什么输出a的值是100?
    答:因为100赋值给了a。

    老师说完我头昏脑涨,完全不明白笑点在哪,后来才知道这是在考察“预编译”这方面的知识。
    总的来说,“预编译”可以分为

    1. 创建GO对象(global object) 发生在页面加载完成时
    2. 创建AO对象(activation object) 发生在函数执行前一刻

    具体步骤如下:

    全局预编译
    1. 创建GO对象
    2. 找变量声明,将变量声明作为GO对象的属性名,并赋值undefined
    3. 找全局里的函数声明,将函数名作为GO对象的属性名,值赋予函数体
    

      

    局部预编译
    1. 创建一个AO对象
    2. 找形参和变量声明,将形参和变量声明作为AO对象的属性名,值为undefined
    3. 将实参和形参统一
    4. 在函数体里找函数声明,将函数名作为AO对象的属性名,值赋予函数体

    所以那个笑话里的面试问题我们应该这么回答:

    首先,编译器创建一个GO对象
    找到变量声明 var a
    和函数声明 function foo(){}
    将上面两个变量声明作为GO的属性名赋初值
    GO{
        a:undefined
        foo:function(){}
    }
    然后运行第一行代码 a=100
    在GO中将100赋值给a
    再执行第五行代码运行foo函数
    创建一个AO对象
    在函数体内找变量声明和形参,(无)
    再在函数体内找函数声明(无)
    所以
    AO{
        
    }
    完成后运行第三行代码,输出a
    先在AO对象中寻找a的值,发现不存在,向外部作用域扩展,在GO对象中寻找a,发现a的值为100
    输出100
    
    复制代码

    当然,笑话里的题过于简单,但是能让我们清晰的了解到这个“预编译”的进行
    下面,我们来看一道面试题简化版,练练手:

    global = 100
        function fn() {
          console.log(global); 
          global = 200
          console.log(global); 
          var global = 300
        }
        fn()

    它的逻辑和输出结果是多少呢?通过一步步的分析我们可以知道具体的分析应该是这样的:

    GO: {
          global: undefined => 100,
          fn: function() {}
        }
        global = 100 // 没有声明的变量默认为全局变量,也会放到GO中
        function fn() {
          console.log(global); // 输出undefined
          global = 200
          console.log(global); // 输出200
          var global = 300
        }
        AO: {
          global: undefined => 200 => 300
        }
        fn()



    转自:https://juejin.cn/post/6954393788001288199

  • 相关阅读:
    .net正在终止线程异常
    js判断客户浏览器类型,版本
    C#中ToString格式大全
    WPF TextBox 搜索框 自定义
    C#:获取设备电量相关信息
    C#中的委托与事件并存的理由
    WPF中的Pack URI
    SQLServer中的数据库备份和还原
    使用Aspose.Cells读取Excel
    SQLServer存储过程事务用法
  • 原文地址:https://www.cnblogs.com/ndh074512/p/14708331.html
Copyright © 2020-2023  润新知