JS 预编译

JS 运行三部曲

语法分析

语法分析很简单,就是引擎检查你的代码有没有什么低级的语法错误

预编译

预编译发生在代码执行的前一刻,预编译简单理解就是在内存中开辟一些空间,存放一些变量与函数 ;

解析执行

解释执行顾名思义便是执行代码了

预编译前奏

暗示全局变量 imply global

任何变量,如果变量未经申明就赋值,此变量就为 全局对象 所有。

    a = 1;
    console.log(window.a);
    function test() {
        var a = b = 2;
    }
    test();
    console.log(window.b);

全局变量

一切申明的 全局变量, 全是 window 的属性, window 就是全局的域

GO 和 AO

JS 在执行前会产生一个 GO ,也就是我们说的全局作用域 。 当一个方法被调用时会形成一个局部作用域 AO

全局代码在执行的时候,先是 变量提升 , 在全局作用域内添加 属性,然后是 函数(以函数声明创建的函数)提升,再是代码执行

我们先来个简单的小栗子来看看

    var b = 2;
    console.log(b); 
    console.log(b);
    var b = 2;

此时我们打印出来 b 的值为 undefined,那我们不定义 b 直接 打印 b 是什么情况呢

console.log(b);

结果如上图 浏览器报错.

为什么在 console.log 前,后和不定义 b 会有如此大的差别,这就是预编译起到的作用

我们再看看下面这个列子

    console.log(a);
    var a = 123;
    function a() {
    }
    console.log(a);
微信图片_20200111143158.png

结果怎么来的呢???

那我们就得看下面的 预编译 四部曲

预编译四部曲

  • 创建 GO/AO 对象

  • 找形参和变量申明,将变量和形参名作为 AO 属性名,值为 undefined

  • 将实参值和形参值统一

  • 在函数体里面找函数申明,值赋予 函数体

这四部是什么意思呢,我们举个例子看看:

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

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

大家觉得应该输出什么呢?

我们来分析下:

首先方法调用形成一个局部 *AO


AO{

}

找方法里面的形参和变量申明, fn 里面 只有 a 和 b,作为 AO 的属性并把值设置为 undefined


AO{
    a:undefined,
    b:undefined
}

然后将形参和实参的值统一,什么意思呢,就是给 形参 a 赋值为 实参 1,此时的 AO:


AO{
    a:1,
    b:undefined
}

最后一步函数体找函数申明,并赋值为函数体, 我们找到了 函数申明 function a() { } ,有人会问 b呢,不好意思 b 是 函数表达式,因此忽略,此时 AO 为:


AO{
    a:function a() { },
    b:undefined
}

到此 函数预编译完成,下面开始执行:

  • 第一次 console.log(a) 打印即为 AO 里面的 a => function a() { }

  • 第二次 console.log(a) 执行 a 的赋值,此时 a =>123

  • 第三次 console.log(a) 函数function a() { } 已经预编译申明过, 因此直接忽略, a 还是为 123

  • 第一次 console.log(b) 打印即为 AO 里面的 b => undefined

  • 第二次 console.log(b) 执行 b 的赋值,此时 b =>function () { }

我们来看看打印的是否如我们分析的这样:


fn.png

看来没有问题。

好了,我们已经知道了 预编译的过程,那让我们再来一题看看:


function test() {
    console.log(b);
    if (a) {
        var b = 100;
    }
    
    c = 234;
    console.log(b);

    console.log(c);
}

var a;
test();
a = 10;
console.log(a);
console.log(c);

一样的,我们首先生成 GO,AO

GO{
    a:undefined
}

AO{
    b:undefined
}
  • 第一次打印 b 的值 为 undefined 没问题,

  • 此时 AO 中没有a 属性,往上找全局属性 GO ,ok a 为 undefined,条件不成立 b 还是 undefined

  • 打印 c 没什么好说的,直接就是 234

  • 函数 test() 执行完毕 下面 a 进行复制, 因此 打印 a 为 10

  • 打印 c 相当于 访问 window.c 因此还是 234

小练习


    a = 100;
    function deme(e) {
        function a() { }
        arguments[0] = 2;
        console.log(e);
        if (a) {
            var b = 123;
            var c = function () { }
        }
        var c;
        a = 10;
        var a;
        console.log(b);
        f = 123;
        console.log(c);
        console.log(a);
    }

    var a;
    deme(1);
    console.log(a);
    console.log(f);

总结

  1. 未经申明就赋值,此变量就是全局变量所有,一切申明的全局变量,全是 window 属性

  2. 预编译发生在 变量申明函数申明, 匿名函数函数表达式 不参与预编译

  3. 变量 声明提升—无论变量调用和声明的位置是前是后,系统总会把声明移到调用前,注意仅仅只是声明,所以值是 undefined

  4. 函数声明整体提升-无论函数调用和声明的位置是前是后,系统总会把函数声明移到调用前面.如果函数名同形参或变量名同名,则会赋值为 函数体

  5. 只有在解析执行才会对变量初始化

觉得不错请帮忙点个赞,谢谢!!!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,440评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,814评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,427评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,710评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,625评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,014评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,511评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,162评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,311评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,262评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,278评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,989评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,583评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,664评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,904评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,274评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,856评论 2 339

推荐阅读更多精彩内容

  • 预编译是js的一个特色,也算是闭包之前最难的一个知识点。 预编译有4句公式,而这4句公式只要背熟就能理解预编译。 ...
    德育处主任阅读 1,435评论 0 7
  • 之前学习了一些预编译的知识,一直没有作总结,今天总结一下。 大家都知道,javascript是解释性语言,主要特点...
    蛋挞一点也不甜阅读 394评论 1 0
  • 输出: 原因: js执行前会进行预编译全局预编译GO(Global Object)创建GO对象给全局变量赋值 un...
    文刀强阅读 1,846评论 0 2
  • JS三部曲:语法分析:js代码的执行是读一行代码执行一行,但在执行之前系统会先对js进行全面扫描检查是否存在低级的...
    WangYatao阅读 1,876评论 0 4
  • 6岁时我最想要个芭比娃娃,可以每天给她穿衣服,12岁时我想数学可以考100分,父母可以请我吃好吃的,18岁时我...
    思域22阅读 310评论 1 0