【Udemy - JavaScript】How JavaScript works behind the scenes

1、JavaScript引擎和运行时间

(1)JavaScript引擎:Google的V-8、Node.js……

        调用栈(call stack):代码实际执行的地方,使用执行上下文(Execution context)

        (Heap):非结构化的内存池

 (2)代码运行:编译(compilation)或解释(interpretation)

                编译:代码→可执行文件→运行

                解释:代码→运行(运行速度非常缓慢,JS曾经使用)

        →即时编译(Just-in-time,JIT compilation)

 JavaScript编译语言的过程:代码→解析→抽象语法树(Abstract Syntax Tree,AST)→编译→机器码→执行(执行中进行优化)

 (3)JavaScript Runtime

         Web API:为JavaScript提供需要的功能

        回调函数(Callback Function):【回调队列→调用栈→回调队列】→事件循环

2、JavaScript代码运行

(1)执行上下文(Execution context):一种JavaScript的执行环境,为顶级代码(top-level code)创建,包含所有必要的信息,函数只在调用的时候执行

        ①内容:

                可变环境(variable environment)(变量、函数、参数对象)

                作用域链(scope chain)

                this关键词(this keyword)

        ②执行顺序:执行上下文会堆放在调用栈中,先进后出

(2)运行

(3)函数运行:执行函数,等待回调函数

3、作用域(scope)

(1)分类

        ①全局作用域(Global scope):在任何函数或代码块以外,变量能在任何地方被调用

        ②函数作用域(Function scope):局部作用域(local scope),只能在函数内部调用

        ③块作用域(Block scope):大括号内声明的变量只能在内部调用(只限于let和const,但是用var可以在外部被调用),函数也是块范围的

 (2)作用域链(Scope chain):先在自身作用域找,子作用域可以调用上层作用域声明的变量(变量查找),同级作用域无法互相查找

4、可变环境(Variable environment)与提升(Hoisting)

(1)提升(Hoisting):变量可以在声明之前被调用

                函数声明:存放在可变环境中,甚至比代码执行还早,所以可以在声明前被调用

                var变量:实际值为undefined

                let和const变量:不会被提升,不能在声明之前被调用→TDZ(Time dead zone)

                函数表达式、箭头:取决于是否由var或let、const创建→两种不同的错误

 (2)时间死区:let和const变量存放在此,知道存在,但是未初始化,不能被调用,便于发现错误,让常量变量const不能重新分配值

(3)总之:尽量声明所有的变量和函数在调用之前,让代码更干净易读。

6、this关键字

(1)this:一种特殊的变量,指向所有者(调用函数的对象

(2)四种调用方式

        箭头函数没有this关键字,直接指向全局的this

        使用var时实际上会在全局创建变量,因此如果同时使用var声明了一个变量,又在箭头函数中使用this关键字调用一个同名变量,this会直接指向该var变量

(3)Object内函数嵌套this问题:

        ①在父函数中声明const self = this,在子函数中使用self,这样在调用self时就会提升到上一层函数的this

        ②子函数采用箭头函数:箭头函数的this直接指向上一层函数的this

 (4)arguments:一个类数组对象,可以通过索引来操作数据,也可以获取长度。arguments 代表的是实参。在调用函数时,我们所传递的实参都会在arguments 中保存。

        arguments只在函数中使用,箭头函数没有arguments关键字

7、原始类型(Primitives)和对象(Objects)

(1)原始类型储存在调用栈中,对象存储在堆中

 原始类型→调用栈→标识符(Identifier)→地址(Address)、值(Value)

对象→对象名存储在调用栈→对象内容存储在堆

 (2)复制对象:Object.assign({}, object); →将复制的对象与一个空对象合并→新对象

        浅拷贝→只复制第一层,要是对象里有对象,那个对象依然在堆中指向同一个地址

        深度克隆→Lodash

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值