5分钟懂一个知识点系列之预编译

5分钟一个前端知识点系列预编译 通过预编译JavaScript引擎能够准确地知道哪些变量和函数在哪个作用域内可用,有助于避免变量污染和命名冲突。总的来说是必须掌握的知识。如果你能把上面的例子都理解明白的话我相信你可以掌握这个知识点了。以后也会更新5分钟系列的>_ 阅读详情

前言

预编译是JavaScript中一个重要的概念指的是在代码实际执行之前,JavaScript引擎会先进行一系列的准备工作,以确保代码能够按照预期运行。这个过程主要包括变量声明的提升(hoisting)和函数声明的提升,以及执行环境的初始化全局预编译函数预编译也不太相同,今天通过5分钟就让你搞懂这个知识点。

全局预编译

我先讲一下这里全局预编译的过程:

1. 创建全局执行上下文对象 GO
2. 找变量声明,变量名作为Go的属性名,值为undefined( 变量提升 )
3. 在函数声明,函数名作为Go的属性名,值为函数体
这里属性和方法名都是存在GO对象中,你要先明白一个先前知识点就是对象中不能存在相同的属性名,如果已经存在了则会对之前的属性值进行覆盖.比如

obj.a =1
obj.a =2
console.log(a)//这里打印的是2

是不是很简单,我们一起用一个例子来先试试看。

console.log(str);
var str ="123";
console.log(str);

来!跟着我一起按照上面的步骤思考一下答案:

    1-首先全局编预译在全文创建一个函数体
    GO ={
    }
    2-找变量声明,变量名作为Go的属性名,值为undefined( 变量提升 )
    //这里就将str进行变量提升
    GO ={
        str : undefined
    }
    3-在函数声明,函数名作为Go的属性名,值为函数体
    //这里没有函数所以就可以跳过啦
    全局预编译就完成了!
    
    预编译完成之后然后就开始执行代码编译部分
    首先遍历到console.log(str);
    此时str的值为undefined,所以打印的是undefined,
    然后遍历var str ="123",则obj对象里面的str就变成了123.
    GO ={
        str :"123"
    }
    最后执行打印str就输出打印123

 是不是感觉很简单,接下来跟我一起来一点进阶的 

    console.log(f);
    var f = 123;
    console.log(f);
    function f(){}
    console.log(f);

注意别掉队,要开始发车了!

 1-首先全局编预译在全文创建一个函数体
 GO ={
 }
 2-找变量声明,变量名作为Go的属性名,值为undefined( 变量提升 )
 GO ={
     f : undefined
 }
 3-在函数声明,函数名作为Go的属性名,值为函数体
 GO ={
     f : function f(){}
 }
 
 预编译完成,开始执行代码
 console.log(f);//打印function f(){}
 var f = 123;//赋值f为123
 则GO ={
     f:123
 }
 console.log(f);//打印为123
 function f(){}//这里只是方法声明,在预编译已经执行完成,所以这里不执行
 console.log(f);//打印123

如何?你有没有写对呢?

函数预编译

函数预编译就是执行函数时开始进行,而不是声明函数时开始预编译这个要搞明白。

我先讲一下这里函数预编译的过程:

1-创建一个AO对象
2-寻找变量,GO对象里面创建属性为变量,初始化赋值为undefined(进行变量声明( 变量提升 ))
3-形参和实参进行统一(将GO里面创建属性为形参的名字,值为形参值)
4-寻找函数声明,GO对象里面创建属性为函数名,初始化赋值为function 变量名(){}(进行函数声明(函数提升,整体提升))

老规矩先来一个简单题:

function fn(str){
    console.log(str);
    var str ="123";
    console.log(str);
    function str(){
    }
}
fn("abc");
1-创建一个AO对象
AO ={}

2-寻找变量,GO对象里面创建属性为变量,初始化赋值为undefined(进行变量声明( 变量提升 ))
AO ={
    str : undefined;
}

3-形参和实参进行统一(将GO里面创建属性为形参的名字,值为形参值)
AO ={
    str :"abc"
}

4-寻找函数声明,GO对象里面创建属性为函数名,初始化赋值为function 变量名(){}
AO ={
    str :function str(){}
}

预编译已完成开始执行代码
第一行console.log(str)则打印的是function str(){}

第二行进行str赋值为123

第三行console.log(str)则打印则是123

第四行函数声明不执行

你以为我要开始第二个简单题了吗?错!我开始出一题融合难题给你了

首先我的再次声明函数预编译就是执行函数时开始进行,而不是声明函数时开始预编译这个要搞明白。 所以顺序是先全局预编译,然后进行代码执行,执行到函数方法时,才开始函数预编译!如果局部对象中不存在的属性将会去上一级对象中查找,直到查找到全局对象。 没有则报错!

综合题

console.log(str);
var str;
str();
function str(str){
    console.log(str);
    str =123;
}
console.log(str);

老规矩开始分析

 
1. 创建全局执行上下文对象 GO
GO ={}
2. 找变量声明,变量名作为Go的属性名,值为undefined( 变量提升 )
GO ={
    str : undefined
}
3. 在函数声明,函数名作为Go的属性名,值为函数体
GO ={
    str : function str(){}
}

全局预编译完成!开始执行代码
第一行 console.log(str)打印function str(){}
第二行 var str;变量声明并没有进行赋值操作则不执行
第三行 str();开始执行str函数
进行函数预编译

    1-创建一个AO对象
        AO ={}
    2-寻找变量,GO对象里面创建属性为变量,初始化赋值为undefined(进行变量声明( 变量提升 ))
        没有变量声明则不操作
    3-形参和实参进行统一(将GO里面创建属性为形参的名字,值为形参值)
        没有形参则不操作
    4-寻找函数声明,GO对象里面创建属性为函数名,初始化赋值为function 变量名(){}
        没有函数声明则不操作
        
    开始执行函数代码
    console.log(str);AO对象中没有str属性则去上一级对象中也就是全局对象找str,找到打印
    function str()
    
    str =123 没有str属性则去上一级对象中也就是全局对象找str,赋值123
函数执行完毕
    
console.log(str);打印123

 

怎么样你想对了没!

总结

通过预编译,JavaScript引擎能够准确地知道哪些变量和函数在哪个作用域内可用,有助于避免变量污染和命名冲突。总的来说是必须掌握的知识。如果你能把上面的例子都理解明白的话我相信你可以掌握这个知识点了。如果还喜欢的话请点赞和关注吧!以后也会更新5分钟系列的>_<.

文章转自:https://juejin.cn/post/7372757076937474083

JS预编译 今天有幸获得腾讯的电话面试,不幸的是面试非常惨,但是从中认识到自己的不足和找到日后该努力的方向,就拿面试中的关于js预编译来说吧,小编都不知道是啥,面试完后赶紧查资料,写总结。 首先javascript解释型语言,自然就是编译一行,执行一行。js运行过程分为三步:1、语法分析 2、预编译  3、解释执行 语法分析就是指js引擎去判断检查你的代码是否存在语法错误,解释执行更不用多说,自然就是 阅读详情

相关推荐

前端预编译

预编译JavaScript绕不过去的一道坎,有关的题更是层出不穷,今天就由我来彻底的解析什么是前端预编译。  js有GO对象(global object)和AO对象(active object),先来讲GO对象, 进入script标签,在执行代码前的一瞬间会生成一个GO对象 分析var声明,变量名为GO对象的属性名,值为undefined,如果变量名重名,不用发生任何改变 分析函数声明,变量名为GO对象的属性名,值为函数体,如果变量名重名,直接覆盖属性值。 搞了这些,接下来就直接上代码。 //.

hutao2333的博客 1275

前端预编译流程

前言我是歌谣 最好的种树是十年前 其次是现在 今天继续给大家带来的是预编译基础的讲解环境配置npm init -y yarn add vite -D修改page.json配置端口{ "name": "demo1", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "...

qq_41632427的博客 104

前端学习——02——js预编译过程详解易附代码

一:函数体系内的预编译 ​ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta...

x1037490413的博客 1075

js预编译ao对象及go对象,js预编译是什么意思

JavaScript代码在执行之前首先经过预编译预编译的过程中函数声明会被整体提升,变量只有声明被提升,赋值留在原地Python中的所有运算符号。// 此写法等同于// b = 7;// 且从右往左执行// 在一个函数中给一个未定义的变量赋值,// 此变量会被挂载到window对象上// 7 7// 此处的b被挂载到window上了fn();// 2fn();foo();

chatgpt001的博客 206

5分钟一个前端知识点系列之作用域链与闭包

闭包优点:实现封装和模块化,允许数据隐藏,支持函数式编程特性,如柯里化和偏应用。保持状态,适用于计数器、缓存等场景。闭包缺点:可能导致内存泄漏,未及时释放不再使用的资源;过度使用可能引起理解难度增加,影响代码可读性。所以大家在平常使用的时候,要注意不要过度使用闭包哦。使用可以但不要过量哦。好了本次5分钟系列到此结束!喜欢的话点个关注吧,内容持续更新中。。。

qq_62012466的博客 1057

5分钟JavaScript预编译流程

大家都知道JavaScript解释型语言,既然是解释型语言,就是编译一行,执行一行,那又何来预编译一说呢?脚本执行js引擎都做了什么呢?今天我们就来看看吧。 1-JavaScript运行三部曲 语法分析 预编译 解释执行 语法分析很简单,就是引擎检查你的代码有没有什么低级的语法错误; 解释执行顾名思义便是执行代码了; 预编译简单理解就是在内存中开辟一些空间,存...

188

Windows平台Poppler预编译版终极指南:5分钟搞定PDF处理环境

还在为Windows系统配置PDF文档处理工具而烦恼吗?Poppler预编译Windows版本让您轻松获得完整的PDF解析能力。作为业界领先的PDF处理库,现在通过预编译二进制包,彻底解决了传统编译的复杂性问题。 ## 🎯 为什么选择预编译版本? 相比传统编译方式,Poppler预编译版本具有以下显著优势: **即装即用体验** - 无需配置复杂的开发环境 - 自动处理所有依赖关系 - 避

gitblog_00953的博客 392

java预编译js预编译_5分钟JavaScript预编译流程

大家都知道JavaScript解释型语言,既然是解释型语言,就是编译一行,执行一行,那又何来预编译一说呢?脚本执行js引擎都做了什么呢?今天我们就来看看吧。1-JavaScript运行三部曲语法分析预编译解释执行语法分析很简单,就是引擎检查你的代码有没有什么低级的语法错误; 解释执行顾名思义便是执行代码了; 预编译简单理解就是在内存中开辟一些空间,存放一些变量与函数 ;2-JS预编译什么时候发生...

weixin_33701379的博客 264

Windows PDF处理神器:Poppler预编译5分钟快速上手

还在为Windows下PDF处理的复杂依赖而烦恼吗?Poppler预编译包为Windows用户带来了终极解决方案!这个开源项目将强大的PDF处理工具链打包成开箱即用的完整套件,让你无需编译就能享受**PDF文本提取、图像转换、文档分析**等核心功能。无论是开发人员还是普通用户,都能在几分钟内搭建好专业的PDF处理环境。 ## 📊 为什么你需要Poppler预编译包? 在Windows上进行P

gitblog_00223的博客 198

如何5分钟搞定Windows PDF处理:Poppler预编译包完整指南

还在为Windows上的PDF处理工具配置烦恼吗?想要快速获得一个功能完整的PDF处理工具链却不想花几小时编译依赖?poppler-windows项目为你提供了终极解决方案!这个开源项目通过自动化脚本从conda-forge官方源获取预编译的Poppler二进制文件及其所有依赖,打包成一个即用型的工具包,让你在5分钟内就能拥有强大的PDF处理能力。 ## 🔍 为什么选择Poppler预编译包?

gitblog_00767的博客 246

前端面试必备(1)预编译

目录我们先看这道题:预编译预编译的时候做了哪些事情?那么这个AO对象在函数作用域的创建阶段做了哪些事情呢?js解释执行 逐行执行gitee仓库地址获取代码:https://gitee.com/CMD-UROOT/case-interview建议自己先思考怎么解决,再看解题思路 解决这道题我们需要了解预编译 作用域的创建阶段就是预编译的阶段作用域分为全局的作用域和函数的作用域在函数的作用域创建阶段与之对应的有一个js的变量对象(也称为AO对象) ,我们是访问不到的,是供js引擎自己去访问的1.创建了

qq_46368050的博客 406

【学习】tmodJS——前端模板预编译技术

什么是前端模板预编译前端模板预编译通过预编译技术让前端模板突破浏览器限制,实现后端模板一样的同步“文件”加载能力。它采用目录来组织维护前端模板,从而让前端模板实现工程化管理,最终保证前端模板在复杂单页 web 应用下的可维护性。同时预编译输出的代码经过多层优化,能够在最大程度节省客户端资源消耗。按文件与目录组织模板template('tpl/home/main', data)模板支持引入子模板{{i

思诚^_^ 6687

web前端Javascript开发学习之JavaScript中的预编译如何进行

预编译又称预处理,是整个编译过程最先做的工作,即程序执行前的一些预处理工作。在这种情况下,可以将所有包含文件预编译一个预编译头。先在AO对象中寻找a的值,发现不存在,向外部作用域扩展,在GO对象中寻找a,发现a的值为100。找形参和变量声明,将形参和变量声明作为AO对象的属性名,值为undefined。当然,笑话里的题过于简单,但是能让我们清晰的了解到这个“预编译”的进行。在函数体里找函数声明,将函数名作为AO对象的属性名,值赋予函数体。找全局里的函数声明,将函数名作为GO对象的属性名,值赋予函数体。

xuezhangmen的博客 583

2024年前端最全JavaScript预编译学习(附带多个面试题)_预编译面试题(2),2024年最新面试官经典问题

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】大厂面试问深度,小厂面试问广度,如果有同学想进大厂深造一定要有一个方向精通的惊艳到面试官,还要平时遇到问题后思考一下问题的本质,找方法解决是一个方面,看到问题本质是另一个方面。还有大家一定要有目标,我在很久之前就想着以后一定要去大厂,然后默默努力,每天看一些大佬们的文章,总是觉得只有再学深入一点才有机会,所以才有恒心一直学下去。第一个console.log(a);// 此时AO中a的值为function a() {}

2401_84433974的博客 666

前端面试题--预编译

文章目录知识点面试题推论及注意事项 知识点 预编译4步: 1 创建AO对象 2 找形参和变量声明 3 实参和形参统一 4 找函数声明,并覆盖变量声名 面试题 function fn(a,c){ console.log(a) var a = 123 console.log(a) console.log(c) function a(){ if(false){

李卓书 276

javascript基础--预编译、this指向

javascript预编译 预编译发生在函数执行前一刻,可以拆分成一下几步 1、生成Activation Object 即AO对象(执行期上下文) 2、查找形参和变量,并将其作为AO对象的属性,值为undefined 3、将实参的值赋给形参 4、在函数体内查找函数声明,并将值赋予函数体 看看下面的例子: function fn(a) { console.log(a); // a =&g...

W_wjl1900的专栏 390
上一篇: 小众 CSS 新特性
下一篇: 前端程序员快速学会 Redis
前端77
博客等级 码龄2年 2862粉丝 · 306原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值