深入理解 JS | 青训营笔记

91 阅读3分钟

深入理解 JS

如果说前端三剑客最重要的是谁,那毫无疑问就是能执行各种 script 和Function 等等的 JavaScript 了。基本上功能的实现、主要的逻辑代码还是以JavaScript为主,各种测试的比重也是倾向于JS。让我们今天一起来学学 JavaScript 吧。

01 JS的基本概念

复杂数据类型和基础数据类型区别:

在JS里,复杂数据类型赋值的是地址,基础数据类型赋值的是值。

复杂数据类型的原始值可以被改变,基础数据类型不可被改变,类似常量。

作用域:

变量的可访问性和可见性

静态作用域,通过她就能够预测代码在执行过程中如何查找标识符

全局作用域

var company ="Bytedance";

function showCompany(){
    console.log(company);
}

showCompany()

函数作用域

var company ="Bytedance";

function showCompany(){
    company="douyin";
    console.log(company);
}

showCompany() // douyin

块级作用域

{
    const company ="Bytedance"; //只在括号内生效
    console.log(1,company);
}
    console.log(2,company); // error

变量提升

JS-var-upgrade.png

使用 let 、const 时,没有变量提升。例如你在定义前访问了 const,这样会导致报错。

使用 var 的时候,会有变量提升,例如提前访问的时候,会先给var 赋值为 undefined。(下面会赋值真实值)

使用 Function ,也会有提升,不过是把整个函数定义提升。函数会存在词法含义。

如果把 Function 赋值给 const var变量然后再调用,const 会直接报错,var 会提示is not a function,因为会被赋值为 undefined。

JS是怎么执行的

JS-how-excute.png 源码通过 词法分析和语法分析,生成AST,还会创建执行上下文(Context)。

生成AST后,会转化成字节码,然后逐行解释执行字节码,节约开销。

JIT 字节码编译执行,V8把多次出现的字节码直接转为机器码储存。

执行上下文:

JS-excute-context.png

Execution Context(EC):包含变量环境、词法环境、This 和可执行代码。

有三种EC:全局执行上下文、函数执行上下文、Eval执行上下文。

  • 全局EC:代码开始执行时就创建,压到执行栈的栈底(永远都在栈底)。每个生命周期只有一份
  • 函数EC:执行一个函数时,函数内的代码会被编译,生成变量环境、词法环境等,当函数执行结束时该执行环境从栈顶弹出。

调用栈

JS-Exection-call-stack.png

以 Chrome为例,调用栈是有限的,大概2W多,死循环太多会栈溢出。

创建执行上下文期间做了什么
  • 绑定This
  • 创建词法环境
  • 创建变量环境

JS-Execution-env.png

词法环境放函数、const 定义变量,变量环境放var

Outer:指向全局的EC,外部是指不在func内的。

JS-Execution-outer-find.png

Outer 往上进行层级查找(例如 test2 去找 test1),找到最后再去全局EC找。这个就是作用域链。

JS-var-env.png

变量环境存储 var 等基础数据类型。

例如 person 这个Object 是存的内存地址,指向堆空间上的一块内存。内存存着 person 真正的内容。

把person 赋值给 a ,其实是赋值了内存地址,修改a会把堆空间的内容更改。 解释了为什么前面改了 b 把a也改了.

JS-ESP.png

ESP(记录当前执行状态的指针):

例如执行完了 func EC,就会弹出,指向全局EC。fuc EC 就会变成无效内存。

如果执行全局EC,有func 2 的来执行EC,会把func 1 的EC 覆盖掉。这样也就完成了栈上面的垃圾回收。

03 JS进阶知识

闭包

JS-Closures.png

返回的func 访问了dep 和 name。创建的闭包 ShowName(closure),是一个地址。闭包访问了dep和name,就赋值进来。

因为赋值到 getName,所以这个闭包会等到getName 结束。

闭包的缺点是内存不容易被回收,闭包的本质是没被回收的对象

This

JS-adv-this.png

垃圾回收:

JS-Garbage-collection.png