Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >重学JS基础-预编译

重学JS基础-预编译

作者头像
Jou
发布于 2022-08-10 12:54:10
发布于 2022-08-10 12:54:10
46400
代码可运行
举报
文章被收录于专栏:前端技术归纳前端技术归纳
运行总次数:0
代码可运行

预编译

1.JS代码的执行步骤

  1. 语法分析: 主要扫描代码有没有语法上的错误(比如少些括号,写了中文符号)
  2. 预编译: 进行变量的声明提升,函数整体提升,函数执行前一刻的准备工作。
  3. 解释执行: 对js代码进行执行,解释一行,执行一行。

2.预编译的前奏

  1. 暗示全局变量:任何变量未经声明就赋值,此变量归全局所有。
  2. 一切全局变量都是window的属性

例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var a = 100;
console.log(window.a); //100
if(1){
    a = 10;
}
console.log(window.a); //10

3.预编译

脚本代码块script执行前,系统执行的操作

  1. 创建一个GO对象,即window全局对象
  2. 查找全局变量声明(包括隐式全局变量声明,省略var声明),变量名作全局对象的属性,值为undefined
  3. 查找函数声明,函数名作为全局对象的属性,值为函数引用

例如

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
console.log(a);     //undefined
console.log(func);  //func
var a = 100;
function func(){
    return 1;
}
注意:
  1. let和const也会有变量提升,但是在声明之前并不能访问到,因为存在一个暂时性死区。
  2. 函数声明出现在 if 等语句中的情况有点复杂,它仍然作用于脚本、模块和函数体级别,在预处理阶段,仍然会产生变量,它不再被提前赋值,所以下面的代码打印undefined。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

console.log(foo);
if(true) {
    function foo(){

    }
}
  1. with关键字能改变代码块内的作用域,所以在使用的时候需要格外注意。这里打印2和underfined,因为在foo函数中,a会被变量提升,但是赋值的时候指定了对象o的作用域,所以只改变了o.a的值。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var a = 1;

function foo() {
    var o= {a:3}
    with(o) {
        var a = 2;
    }
    console.log(o.a);
    console.log(a);
}

foo();
  1. class 声明在全局的行为跟 function 和 var 都不一样。在 class 声明之前使用 class 名,会有变量提升,但是会抛错。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
console.log(c);
class c{

}

4.函数执行上下文

函数在执行前会先做下面的操作 1) 创建一个AO对象(执行期上下文) 2) 找到函数体中定义的变量和函数形参,变量名作为AO的属性名,值为undefined 3) 将实参和形参统一 4) 将定义的函数名挂在AO的属性中,值为函数体。 如果有兴趣,可以看一下这一道面试题

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
a = 100;
function demo(e){
    function e(){}
    arguments[0] = 2;
    console.log(e);
    if(a){
        var b = 123;
        function c(){}
    }
    var c;
    a = 10;
    var a;
    console.log(b);
    f = 123;
    console.log(c);
    console.log(a);
}
var a;
demo(1);
console.log(a);
console.log(f);

打印结果是

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2
undefined
undefined
10
100
123
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-07-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
前端学习(35)~js学习(十二):预编译
规律1:任何变量,如果未经声明就赋值,此变量是属于 window 的属性,而且不会做变量提升。(注意,无论在哪个作用域内赋值)
Vincent-yuan
2020/03/18
4700
Js预编译
预编译前奏 1,任何变量未经声明就赋值,此变量就为全局对象所有 a = 123 console.log(a); // 123 var a = b = 123 console.log(a, b); // 123 123 function test() { var a = b = 123 } test() console.log(b) // 123 2,一切声明的全局变量,全是window的属性 <script> // a = 123 // console.log(a); // 123 // v
hss
2022/02/25
8030
JavaScript的预编译过程
在全局环境中会生成一个 GO对象 (Global Object),还是按照上面的四步执行。
FinGet
2019/06/28
4150
JavaScript的预编译过程
【JS】预编译详解
函数dmeo为经声明就可正常调用,执行函数demo时,先将1赋值给b,再将b的值赋值给a;虽然a、b是在函数作用域中,但由于b未经声明,所以下面在browser环境中输出的结果表明b 在 window 属性中,而 a 则不会出现在全局对象中;函数demo的声明是在全局作用域,所以它归window对象所有
好吃懒洋洋
2022/11/15
1.4K0
【JS】预编译详解
JavaScript的预编译过程分析
顾名思义 就是检查一遍js代码内有没有出现语法错误(比如少些个分号,多写个括号等);语法分析期间不会执行代码
九旬
2020/10/23
7040
一道问题引起的重学预编译
实际上,变量的提升其实算是JS的诟病了,所以es6出来了 let和 const之后,都是推荐使用 let和 const了。
赤蓝紫
2023/03/11
1940
JS学习系列 06 - 变量对象
上一节我们讨论了执行上下文,那么在上下文中到底有什么内容,为什么它会和作用域链扯上关系,JS 解释器又是怎么找到我们声明的函数和变量,看完这一节,相信大家就不会再迷惑了。
leocoder
2018/10/31
1.4K0
js 预编译法则
第一个输出function a(a){ ... } , 在函数外部,就是看GO 全局上下文的执行顺序,这就是函数提升了
用户9914333
2022/07/22
7420
重学JS基础-作用域链和闭包
JS有一个全局对象,window,在全局声明的变量都属于window的属性,未使用声明符声明的属性也是window的属性。
Jou
2022/08/10
6180
JS学习系列 06 - 变量对象
上一节我们讨论了执行上下文,那么在上下文中到底有什么内容,为什么它会和作用域链扯上关系,JS 解释器又是怎么找到我们声明的函数和变量,看完这一节,相信大家就不会再迷惑了。
leocoder
2024/02/01
1510
JS学习系列 06 - 变量对象
JS预编译
js预编译 创建AO对象 找函数形参和变量声明,值给undefined 实参形参统一 在函数体里面找函数声明,值赋予函数体 function fn(a){ console.log(a); //在AO里找值--->输出 function a() {} var a = 123; //预编译将 var a,提升上去了,执行 a = 123;修改AO中a的值 console.log(a); //输出 123 function a() {} //预编译读过,不再读 console.log
小丞同学
2021/08/16
7860
JS入门难点解析5-变量对象
(注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!) (注2:更多内容请查看我的目录。)
love丁酥酥
2018/08/27
1.2K0
我理解的JavaScript预编译
JavaScript执行过程首先先语法分析,就是分析一遍代码有没有语法错误,解析期间不会执行代码。接着就开始预编译,预编译完了就开始一行一行执行代码。
wade
2020/04/23
4680
javascript预编译(执行期的上下文)
这句话很重要,函数执行之前也就是在这段程序开始之前,浏览器对马上要执行的函数进行预编译!! 预编译四部曲
ZEHAN
2020/09/27
5210
前端学习(34)~js学习(十一):作用域和变量提升
作用域:通俗来讲,作用域是一个变量或函数的作用范围。作用域在函数定义时,就已经确定了。
Vincent-yuan
2020/03/18
7730
ECMAScript 6入门 - let和const命令详解
let命令 基本用法 ES6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。 'use strict'; { let a = 10; var b = 1; } a // 报错,ReferenceError: a is not defined. b // 1 不存在变量提升 let不像var那样会发生“变量提升”现象。所以,变量一定要在声明后使用,否则报错。 'use strict'; console.log(foo); // 输出unde
laixiangran
2018/04/11
8550
var、let和const之间的区别
即 let和 const不需要先声明,再使用,否则会报错,而 var不需要先声明再使用,可以先使用后声明,不会报错,不过赋值的时候,值一直是 undefined
赤蓝紫
2023/03/11
1.5K0
var、let和const之间的区别
React 语法之let和const命令
let命令 基本用法 ES6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。 { let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1 上面代码在代码块之中,分别用let和var声明了两个变量。然后在代码块之外调用这两个变量,结果let声明的变量报错,var声明的变量返回了正确的值。这表明,let声明的变量只在它所在的代码块有效。 for循环的计数器,就
xiangzhihong
2018/02/05
6.5K0
js堆栈内存详解
变量提升:当前上下文执行之前,会把var/function声明或者定义提升,带var的只声明,带function的声明+定义
花落花相惜
2021/12/15
2K0
js堆栈内存
变量提升:当前上下文执行之前,会把var/function声明或者定义提升,带var的只声明,带function的声明+定义
ruochen
2021/11/21
1.9K0
相关推荐
前端学习(35)~js学习(十二):预编译
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验