JS预编译(预编译,函数声明提升问题,一篇足矣)

前言

相信学习过js的人都听说过这两句话:

  • 函数声明整体提升
  • 变量声明提升

这两句话是预编译的简化版,当然只会这两句话做项目的过程遇到一些问题时没有办法解决的,那么本篇就从原理讲这个预编译,学完本篇保证预编译的面试题、以及项目中的bug,通通解决。

一、Js运行过程

首先我们要学习Js的运行过程,这样才会更容易理解这个预编译,我们都知道Js是单线程的解释性语言。
Js运行总共有三部:

  1. 语法分析:在运行之前先给你检测一遍你这个代码,保证你能运行
  2. 预编译:在函数执行的前一刻,会创建一个叫做执行期上下文的(AO)对象这个创建执行期上下文的过程叫做预编译。
  3. 解释执行:前两部都没问题,开始解释代码然后执行

那么第一步和第三步都很简单,第二部也是很难理解的也是我们今天的主角:预编译

二、Js预编译

上面我们也说了,这个预编译发生在函数执行前,那么我们先来看一段代码


    function test(a,b){
        console.log(a);
        console.log(b)
        console.log(c)
        console.log(d)
        var c = 123;
        function d(){

        } 
    }
    test(1);

那么这里的a我们可能大多数人都知道是1,那么b、c、d都输出什么呢?我们预编译就是解决这类问题的。

这个a、b、c、d的值都是从这个执行期上下文(AO对象)中获取值的,那么下面我们就来看看创建这个AO对象的过程也就是预编译:

  1. 创建AO对象 Activation object (执行期上下文)作用域
  2. 找形参和变量声 明,将变量和形参名作为AO属性名 ,值为undefined
  3. 将实参和形参值统一
  4. 在函数体里面找函数声明,值赋予函数体

那么我们再来看上面的代码,这回根据上面的四部曲,是不是就简单了很多呢


//     1. 首先创建AO对象
// AO{


// }
// 2. 找形参和变量声明,将变量和形参名作为AO属性名 ,值为undefined

// AO{
// 	a:undefined,
// 	b:undefined,
// 	c:undefined,
// }
// 3. 将实参和形参值统一 我们在传入的时候传入了一个1
// AO{
// 	a:1,
// 	b:undefined,
// 	c:undefined,
// }

// 4.在函数体里面找函数声明,值赋予函数体

// AO{
// 	a:1,
// 	b:undefined,
// 	c:undefined,
// 	d:function d(){

//         } 
// }

function test(a,b){
        console.log(a);// 1
        console.log(b);// undefined
        console.log(c);// undefined
        console.log(d);// function d(){}
        var c = 123;
        function d(){

        } 
    }
    test(1);

三、练习

那么学完,下面我准备了一道小题,给大家巩固一下知识。


    function fn(a){
        console.log(a);
        var a =12;
        console.log(a);
        function a() {

        }
        console.log(a);
        var b = function (){

        }
        console.log(b);

        function d(){

        }
    }
    fn(1);
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是的,使用`compile()`函数进行预编译可以生成一个`Pattern`对象。`Pattern`对象是一个正则表达式模式的编译形式,可以重复使用,避免每次使用正则表达式时都需要重新编译。`Pattern`对象可以使用`match()`、`search()`、`findall()`等方法进行匹配操作。 下面是一个例子,演示如何使用`compile()`函数进行预编译: ```python import re pattern = re.compile(r'\w+') text1 = 'Hello, world!' text2 = 'Python is awesome!' match1 = pattern.findall(text1) match2 = pattern.findall(text2) print(match1) # ['Hello', 'world'] print(match2) # ['Python', 'is', 'awesome'] ``` 在这个例子中,我们使用`compile()`函数预编译了一个正则表达式模式`r'\w+'`,它可以匹配一个或多个字母、数字或下划线。然后,我们使用这个预编译后的正则表达式模式对两个字符串进行了匹配操作。由于我们使用了预编译后的模式,因此不需要每次都重新编译,可以提高匹配效率。最后,我们打印出匹配结果。 需要注意的是,`compile()`函数的第一个参数是一个正则表达式字符串,第二个参数是可选的标志参数,用于指定正则表达式的匹配模式。如果没有指定标志参数,默认是`0`,表示使用普通的匹配模式。另外,需要注意的是,`compile()`函数返回的是一个`Pattern`对象,而不是一个字符串或匹配对象。如果需要进行匹配操作,需要使用`Pattern`对象的方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值