JS 预解析机制

一、概念

作用域: 域,指的是一个空间、范围、区域,作用指的是在域内可进行读写操作。一个变量的作用域是程序源代码中定义的这个变量的区域。
在ES5中,只存在全局和函数级作用域,在ES6中,引入了块级作用域,js的预解析机制大概分为两个过程:预解析和自上而下逐行解读。
预解析: js解析器会先把var定义的变量、function、参数等一些东西存储进仓库里面(内存)。变量var在正式运行之前,都赋值为undefined,function函数在运行之前,就是整个函数块

预解析结束之后,就是逐行解读

JS解析过程:1、预解析。2、逐行解读代码,下面看几个例子。
注以下演示 JS代码部分

例1:

var value = 1;
var name;
function fn(){var value = 2;}

将会预解析成为:

value = undefined;
name  = undefined;
function fn(){var value = 2; }

例2:

console.log(a);
var a = 1;

执行结果:undefined

console.log(a);
 a = 1;

执行结果:Uncaught ReferenceError: a is not defined
总结:第一种结果是预编译使 a=undefined,第二种结果是直接报错。

例3:

console.log(a);  
var a = 1;
console.log(a);  
function a(){console.log("function a first");}
console.log(a);  
var a = 3;
console.log(a); 
function a(){console.log("function a second");}
console.log(a);  
a();

执行结果:

ƒ a() {console.log("function a second");}
 1
 1
 3
 3
 Uncaught TypeError: a is not a function

我们来分析预编译的过程:
第一行:不是var和function,跳过
第二行:是var,预编译为 a = undefined
第三行:不是var和function,跳过
第四行:是function,因为和第二行的变量重名,则挤掉变量,a变成函数
第五行:不是var和function,跳过
第六行:是var,但是var打不过函数,所以a还是函数
第七行:不是var和function,跳过
第八行:是函数,替代第四行的函数
第九行:不是var和function,跳过
第10行:不是var和function,跳过
最终a的内容是:function a(){console.log(“function a second”);}
预编译处理完成之后执行逐行解读代码
执行第1行:打印出来的为:a(){console.log(“function a second”);}
执行第2行:a = 1
执行第3行:打印出1
执行第4行:函数定义,跳过
执行第5行:打印出1
执行第6行:a = 3
执行第7行:打印出3
执行第8行:函数定义,跳过
执行第9行:打印出3
执行第10行:a还是一个变量,不能当函数来执行,报错

例4:

<script>
    var a = 1;
<script>    
<script>
    console.log(a); //打印出a = 1
<script>  

如果反过来:

<script>
     console.log(a); //报错,a未定义
<script>    
<script>
    var a = 1;
<script>  

结论:预编译时分标签进行的。
第一种情况:a是全局变量,第二块script中可以访问
第二种情况:执行到console.log(a)时,找不到a

例5:

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

结果为:
undefined
1

例6:

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

结果为:
1
2

例7:

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

结果为:
undefined
1

函数中参数a也相当于 var a;

例8:

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

结果为:
1
1

由于函数参数相当于var a;则函数内的 a = 2相当于局部变量而不是全局变量。

动手试一试,书中自有黄金屋,书中自有颜如玉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值