JavaScript的预解析及案例
JavaScript的预解析及案例
author: histonevon@zohomail.com
environment: Google Chrome 84.0.4147.105 (正式版) 64位
edition: ES5
一、代码示例
有以下几段代码:
未声明就直接输出变量
//num未声明
console.log(num);
执行结果为:报错
变量预定义在变量使用前
console.log(num);//使用
var num = 10;//预定义
执行结果为:undefined
在函数声明前或后调用函数
fn();//调用
function fn() {
console.log(11);
}
fn();//调用
执行结果为:正常
在匿名函数定义前通过变量名调用该函数
fun();//调用
var fun = function() {//匿名函数
console.log(22);
}
执行结果为:报错
二、JavaScript的预解析
JavaScript代码是由浏览器中的解析器来执行的
JavaScript解析器在运行JavaScript代码的时候分为两步:预解析和代码执行
预解析:js引擎会把js里所有的 var 变量声明和 function 函数声明提升到当前作用域的最前面
代码执行:按照代码书写的顺序从上往下执行
预解析分为变量预解析(变量提升)和函数预解析(函数提升)
变量提升:就是把所有变量声明提升到当前的作用域最前面,不提升赋值操作
所以,上面第二例的语句实际上等价于:
var num;//声明,不提升赋值 console.log(num); num=10;//赋值
可见,在num使用时还未定义,故结果为undefined
同理,第四例相当于执行如下代码:
var fun;//变量提升不给值 fun(); fun=function(){//赋值 console.log(22); }
fun声明后还未赋值,还不是函数,故报错"fun is not a function"
函数提升:把所有的函数声明提升到当前作用域的最前面,不调用函数
所以第三例为:
function fn() { console.log(11); } fn(); fn();
即,等价于调用两次
匿名函数不可提升(即第四例的情况)
三、预解析案例
结果是几?
var num = 10;
fun();
function fun() {
console.log(num);
var num = 20;
}
相当于执行了以下操作:
var num;//变量提升
function fun() {//函数提升
//函数内部作用域的提升
var num;//变量提升,尚未赋值
console.log(num);//undefined
num = 20;
}
num = 10;
fun();
结果是几?
var num = 10;
function fn() {
console.log(num);
var num = 20;
console.log(num);
}
fn();
相当于执行了以下操作:
var num;
function fn() {
var num;//声明后未赋值
console.log(num);//undefined
num = 20;//赋值
console.log(num);//20
}
num = 10;
fn();
结果是几?
var a = 18;
f1();
function f1() {
var b = 9;
console.log(a);
console.log(b);
var a = '123';
}
var a;
function f1() {
var b;
var a;
b = 9;
console.log(a);//undefined
console.log(b);//9
a = '123';
}
a = 18;
f1();
结果是几?
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
var a = b = c = 9;
相当于var a = 9;b = 9;c = 9;
实际上,由于
=
为右结合,具体过程为:c = 9; b = c; var a = b;
注意 若变量前没有var声明,直接赋值则为全局变量
集体声明的方法为:
var a = 9,b = 9,c = 9;
或多行书写:
var a = 10, b = 11, c = 12;
故,函数内部三个值均为9,函数外部c,d为全局变量,也为9,a为局部变量,故报错"a is not defined"