在预编译阶段,会先创建执行上下文,开始声明变量和函数,声明的变量赋值为undefined,且会发生变量提升和函数提升,提升到当前作用域的顶部。若变量和函数同名,则函数提升优先级高于变量提升。在变量赋值前,函数声明不会被覆盖;当变量赋值后,函数声明会被同名变量覆盖。
js执行过程是什么?
JS代码
执行过程分为两个阶段,编译阶段(或叫预处理、预解析)和执行阶段。在编译阶段 JS
引擎主要做了三件事:
1.词法分析:将代码分解为有意义的单元,如标识符、关键字、运算符和标点符号等;
2.语法分析:构建抽象语法树(AST),检查代码的语法是否正确;
3.预处理:包括变量和函数的声明与提升,值的赋空;
接着 JS
引擎开始创建执行上下文(JS
代码运行的环境)。在执行阶段会逐行执行 JS
代码。
作用域和上下文的区别?
作用域是在编写时就已经被确定好的,执行上下文是被调用时生效。
什么是作用域?
作用域是一个变量绑定的有效范围。就是在这个作用域中变量绑定是有效的,出了这个作用域变量绑定就无效了。也就是说作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。有全局作用域和函数作用域,es6后增了块级作用域。
什么是执行上下文?
执行上下文是对 JS
代码执行环境的一种抽象,每当 JS
运行时都是在执行上下文中运行的。上下文,主要是关键字this的值,这个是由函数运行时决定的,简单来说就是谁调用此函数,this就指向谁。
JavaScript 执行上下文有三种:
全局执行上下文 —— 当 JS 引擎执行全局代码的时候,会编译全局代码并创建执行上下文,它会做两件事:1、创建一个全局的 window 对象(浏览器环境下),2、将 this 的值设置为该全局对象;全局上下文在整个页面生命周期有效,并且只有一份。
函数执行上下文 —— 当调用一个函数的时候,函数体内的代码会被编译,并创建函数执行上下文,一般情况下,函数执行结束之后,创建的函数执行上下文会被销毁。
eval 执行上下文 —— 把字符串当做JS代码执行,不推荐使用。
什么是执行上下文栈?
执行上下文栈,也就是在其它编程语言中所说的“调用栈”,是一种拥有 LIFO(后进先出)数据结构的栈,被用来存储代码运行时创建的所有执行上下文。当JS引擎第一次遇到脚本时,它会创建一个全局的执行上下文并且压入当前执行栈。每当引擎遇到一个函数调用,它会为该函数创建一个新的执行上下文并压入栈的顶部。引擎会执行那些执行上下文位于栈顶的函数。当该函数执行结束时,执行上下文从栈中弹出,控制流程到达当前栈中的下一个上下文。