JavaScript语言是如何构建起来的

JavaScript语言构建的核心-> 静态语法的核心 -> 声明的核心 -> 标识符和值的绑定

1. JavaScript 销毁

  • 什么是引用类型呢?
    引用它是一个数据结构,存储了一个计算的结果,以及可以传递这些结果。

  • delete 删除
    delete 运算符尝试删除值数据时,会返回 true,用于表示没有错误
    delete是在删除 一个表达式的(本质是求值)、引用类型的result-> 结果是一个值/一个引用。

    • delete 0 本质是删除一个表达式的值
    • delete x 本质是删除一个表达式的引用;
    • delete其实只能删除一种引用,即对象的成员( obj.x),
      所以,只有在delete x等值于delete obj.x时 delete 才会有执行意义。

2. 声明语句与语法

  • 声明和语句的区别
    在于发生的时间点不同,声明发生在编译期,语句发生在运行期。
    声明发生在编译期,由编译器为声明的变量在相应的变量表增加一个名字,没有返回值(empty)。--静态语言的处理
    语句是在运行时执行的程序代码。因此,如果声明不带初始化,那么可以完全由编译器完成。--动态语言的处理。
  • 变量声明在引擎的处理上被分成两个部分:
    一部分是静态的、基于标识符的词法分析和管理,它总是在相应上下文的环境构建时作为名字创建的;
    另一部分是表达式执行过程,使用初始器对名字赋值绑定。
  • 变量泄露
    “向一个不存在(未声明)的变量赋值”所导致的变量泄露是不可避免的 => 隐式声明了全局变量 y = 100
  • 例:var x=y=100中,x 和 y 是两个不同的东西,前者是声明的名字,后者是一个赋值过程可能创建的变量名。

3. 表达式

  • 表达式执行与语句声明区别:
    表达式左侧的操作数可以是另一个表达式, x=y=100中 y=100是赋值运算,x=...是表达式,
    “var 声明”语句中的等号左边,x作为标识符, var x=100是值绑定操作

  • a.x=a={n:2}结果?

  var a={n:1},ref=a;
  a.x=a={n:2};
  console.log(ref.x);//-->{n:2}
  console.log(a.x);//-->undefined
  // 产生一个新的a覆盖原始的变量a;“原始的变量a,“a.x”在引用传递中丢失了。
  // 如果有变量、属性或者闭包等,持有了这个“原始的变量a”,那么“a, a.x”不会丢失。

4. 模块&匿名函数表达式

  • 模块导出的内容
    名字和值: 标识符(名字);字面量(由字面含义决定的值);模板(可计算结果的字符串值)
    export default ...值 'default'是收敛到的唯一的名字
  • 导出语句的处理逻辑:
    导出一个名字,以及为其绑定一个值
  • 导出名字与导出值的差异
    本质上并没有差异,在静态装配的阶段,它们都表达为一个名字。
       // 两者等价
        export default function(){}
    
  • 模块装载执行和标识符绑定全过程
    首先export语句声明 初始化名字,再依赖 import形成依赖树,
    执行顶层代码(import),遍历依赖树,给名字绑定值,进行‘变量提升’。
    全程没有表达式被执行!(源代码被理解为静态的,没有逻辑的)
  • export default function(){}:
    并不是导出了一个匿名函数表达式,而是导出了一个匿名函数定义,名字是“default”
    无法导出一个匿名函数表达式.(源代码被理解为静态的,没有逻辑的
  • 所谓匿名函数,仅仅是当它直接作为操作数时,才是真正匿名的

5. 块级作用域的识别与处理

  • for循环并不比使用函数递归节省开销
    循环与函数递归在语义上等价,所以for语句(多行循环体,有大括号)本质上与“在函数参数中传递循环变量的递归过程”完全等价,在开销上也是完全一样的。

  • 块级作用域->解决变量提升存在的变量覆盖、变量污染问题
    ​ - 如何支持变量提升和块级作用域?

    • 执行上下文构成: 变量环境+词法环境+可执行代码
    • 变量环境 管理var声明和函数声明(代码块)的标识符,变量提升是通过变量环境来实现,在更外围的作用域中登记名字行为就称为“提升”
    • 词法环境 管理其它情况下的标识符/变量声明(let/const),通过词法环境的栈结构来实现的,
  • 单语句没有块级作用域,不支持词法声明

  • 块语句在每次迭代都会创建一次块级作用域副本。
    循环体越大,支持的层次越多,环境的创建也就越频繁,代价越高昂。
    加上可以使用函数闭包将环境传递出去,或交给别的上下文引用,负担就更是雪上加霜了

posted @ 2021-12-09 01:31  忘川酒  阅读(32)  评论(0编辑  收藏  举报