JavaScript的预编译过程
Posted 苏苏写bug日记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript的预编译过程相关的知识,希望对你有一定的参考价值。
你真的了解javascript的预编译过程吗?
预编译发生在哪一步呢?
首先要知道js的预编译发生在哪一步
也就是你跟你对象亲热的热火朝天的刚要准备下一步的时候,预编译他来了他来了他骑着白马走来了;你说气不气
预编译是在发生在 这一块代码执行的前一刻
js三步曲
语法解析
语法解析就是,不执行代码通篇看一眼有没有语法错误
比如本应该是一个 英文的分号 ,你这个不争气的手没切换过来键盘 输入成了一个 中文的分号;就是干这事的
预编译
代码在预编译过程中又会发生什么有趣的事情呢?
在解释预编译以前我们先要去铺垫铺垫;好比你喜欢一个女生得先去暗示暗示是吧;让他知道对她有点意思;比如等着没有人的时候拉着女生跟人家说:“我喜欢你”;简单的暗示一下(~ ̄▽ ̄)~
进入正题o( ̄▽ ̄)o
在我们的编程中啊;计算机很人性化对我们很友好;比如下面的代码不会报错;并且会输出5
a = 5;
console.log(a);
而下面的代码一样未经声明他就会报错
console.log(a);
再看这一行代码
console.log(a);
var a = 9;
他会输出的是 undefined
为什么呢??????
先看这一行代码
var a = 5;
这是一个函数声明并赋值;记好下面有用
快快掏出小本本记好了,知识点来了
1、imply global 暗示全局变量;任何变量如果未经声明就赋值;那么该变量归全局所有(window)
是不是太死板了不能理解;φ(゜▽゜*)♪我就知道;我给你简单的解析以下;就是你有一个女朋友没有告诉大家(未经声明);现在好了你女朋友归我们了(window)
这就是上面代码不报错的原因
2、全局上的任何变量不管有没有声明都归全局所有
是不是有点蒙 o((⊙﹏⊙))o
这个window就是全局的域
var a= 5;系统会把这个变量放到哪里去呢 就是放到了window上去了
我们如果要访问这个a 是不是得这样console.log(a)其实console.log(window.a)的结果是一样的
var a= 123;
其实就是
在window{
a:123,
}里创建一个a(或是说把声明的a放到了window里面)
在访问a的时候会上window上去找这个a
所以这样访问a console.log(a)---》就等同于console.log(window.a)
好了啊考题来了;看看你有没有真的理解了
function test(){
var a = b = 123;
}
test();
问 访问window.b会输出什么、访问window.a会输出什么
答案 1、123 答案2、undefined
有没有作对呢?🙄🙄
因为var a = b =123 这一行在执行的时候会按照从右往左的顺序来赋值;这里的b并没有被声明
所以呢 b现在归全局所有了;然而a呢;为什么window.a打印undefined呢?因为这不是在全局声明的变量这是在一个函数内部声明的一个变量所以他不归window所有
重要的在说一遍
任何变量如果未经声明就赋值;那么该变量归全局所有(window)
全局上的任何变量不管有没有声明都归全局所有
预编译 大头来了啊 q(≧▽≦q)
预编译发上在代码执行的前一刻
那么他在这一刻发生了什么呢?
第一步、创建AO对象 Activation Object(执行期上下文)
第二步、找形参和变量声明;将变量和形参名变为AO对象的属性名;值为undefined
第三步、将实参值和形参值同一
第四步、在函数体里找函数声明,赋值予函数体
是不是有个这样的感觉;
function fn(a){
console.log(a);
var a = 123;
console.log(a);
function a(){}
console.log(a);
var b = function(){}
console.log(b);
function d(){}
}
fn(1);
来嘛让你思考几分钟
(~ ̄▽ ̄)~
好了让我来说吧
第一步创建AO对象是吧来
来创建
AO{
}
创建好了
然后第二步
找形参和变量声明;将变量和形参名变为AO对象的属性名;值为undefined
好来呗 找
AO{
a:undefined,
b:undefined,
d:undefined
}
好了 找完了已经
到了第三步了
第三步是什么来着🙄🙄🙄
对 就是 将实参值和形参值同一
AO{
a:1,
b:undefined,
d:undefined
}
好了统一了已经
然后第四步 最后一步咯(* ̄(oo) ̄)
在函数体里找函数声明,赋值予函数体
AO{
a:function a(){},
b:undefined,
d:function d(){}
}
有同学可能会问这不也是一个函数嘛;这是一个函数的赋值;这不是函数声明所以不算
var b = function(){}
好了现在 四步已经完成了
到了函数执行了
function fn(a){
console.log(a);
var a = 123;
console.log(a);
function a(){}
console.log(a);
var b = function(){}
console.log(b);
function d(){}
}
fn(1);
在来看一下这个代码
第一个打印的a是什么呢,这时候回刚刚创建的AO对象里面去找了
这时候的a是function a(){},所以就会打印一个function a(){}然后代码接着往下去执行
看到var a = 123,这时候var a 已经被提取过了 现在执行他只会赋值 然后AO的a的值被改为123了
然后再打印a会输出123;然后再看这时候就不会再看function a(){}因为在预编译的时候已经看过了
所以这时候打印的a还是123 然后下一步 var b = function(){} ;var b 已经看过这里只会赋值 然后AO对象里的b的值被修改为function(){}然后执行下面的代码会打印function(){}。
怎么样是不是很简单呢o(〃^▽^〃)o
解释执行
执行代码;解释一行执行一行
以上是关于JavaScript的预编译过程的主要内容,如果未能解决你的问题,请参考以下文章