JavaScript预解析

2023-04-24


1Q
:未声明变量,直接输出会出现什么结果?

console.log(num);

1A
:报错:变量未被定义。

Uncaught ReferenceError: num is not defined

2Q
:在输出变量后才声明并赋值变量会出现什么结果?
1

console.log(num);

var num = 10;

2A
:显示
undefined

undefined

3Q
:先调用函数,再定义函数会出现什么结果?
2

fn();

function fn() {

    console.log('Javier_Ji');

}3A
:正常显示。

Javier_Ji

4Q
:先调用函数,再声明函数表达式会出现什么结果?
3

fn();

var fn = function() {

    console.log('Javier_Ji');

4A
:错误:
fn
不是函数。

Uncaught TypeError: fn is not a function


解释

JavaScript
代码是由浏览器中的
JavaScript
解析器来执行的。
JavaScript
解析器在运行
JavaScript
代码的时候分为两步:


预解析:js
引擎会把
js
里面的所有的
var
以及
function
提升到当前作用域的最前面。


代码执行:按照代码书写的顺序从上往下执行。


预解析分为:变量预解析(变量提升)和函数预解析(函数提升)


变量提升:把所有的变量声明提升到当前的作用域最前面,不提升赋值操作。


函数提升:把所有的函数声明提升到当前的作用域最前面,不调用函数。


示例


下面的代码执行后会得到什么结果?4

fn();

console.log(c);

console.log(b);

console.log(a);

function fn() {

    var a = b = c = 9;

    console.log(a);

    console.log(b);

    console.log(c);

}


执行后结果如下:

Uncaught ReferenceError: a is not defined


针对2Q
的解答


先预解析,相当于执行了如下代码:


var num;
股票代码https://www.gendan5.com/topic/lcSearch.html

var num;  
//
把变量声明提升到当前作用域(本例中是全局)最前面

console.log(num);
//
执行后续的代码

num = 10;  
//
赋值


针对3Q
的解答


先预解析,相当于执行了如下代码:

function() {

    console.log('Javier_Ji');

}    
//
把函数声明提升到当前作用域(本例中是全局)最前面

fn();  
//
执行后续的代码,函数被正常调用


针对4Q
的解答


先预解析,相当于执行了如下代码:

var fn;  
//

var
声明提升到当前作用域(本例中是全局)最前面

fn();  
//
执行后续的代码,由于函数还没被定义,且
var fn;
语句定义的是变量,则会报错,
fn
不是函数

function() {

    console.log('Javier_Ji');

}    
//
执行后续的代码


针对示例的解答


先预解析,相当于执行了如下代码:

function fn() {

    var a;    

    a = b = c = 9;

    console.log(a);

    console.log(b);

    console.log(c);

}

fn();

console.log(c);

console.log(b);

console.log(a);

       
本例中的代码
var a = b = c = 9;
相当于先在函数内部定义变量
var a
,之后赋值
a = b = c = 9
,由此可得,变量
a
的作用域是在
fn
函数内部,而
b

c
相当于定义了一个全局变量。