【JavaScript】预解析 ① ( 变量预解析 - 变量提升 | 函数预解析 - 函数提升 | 函数表达式预解析 )

文章目录

  • [一、JavaScript 预解析](#一、JavaScript 预解析)
  • 二、变量预解析
    • [1、变量预解析 - 变量提升](#1、变量预解析 - 变量提升)
    • [2、代码示例 - 变量预解析](#2、代码示例 - 变量预解析)
  • 三、函数预解析
    • [1、函数预解析 - 函数提升](#1、函数预解析 - 函数提升)
    • [2、代码示例 - 函数预解析](#2、代码示例 - 函数预解析)
  • 四、函数表达式预解析

一、JavaScript 预解析


JavaScript 代码 是 由 浏览器 的 JavaScript 解析器 执行的 , 执行过程分如下两步 :

  • 预解析
  • 正式执行代码

JavaScript 的 " 预解析 " 又称为 " 变量和函数的提升 " , 会把 var 变量声明 和 function 函数声明 提升到 当前作用域 的 最前面 ;

预解析 机制 允许在代码中 , 无论实际 声明变量 / 声明函数 的位置在哪里 , 解析器 在 预解析 阶段 都会把它们提升到它们各 自的作用域的最顶部 ;

二、变量预解析


1、变量预解析 - 变量提升

变量预解析 又称为 " 变量提升 " , 就是 把 所有的 变量声明 , 提升到 当前 作用域 的 最前面 ;

在 JavaScript 中 , 使用 var 关键字声明的变量 , 会被提升到其所在的 全局作用域 或 局部作用域 的顶部 ;

注意 : 只有 变量 的声明 会被提升 , 初始化操作 不会被提升 , 如果 在声明之前尝试访问一个变量 , 只能访问到 未初始化 的变量值 undefined ;

以下面的代码为例 :

cpp 复制代码
// 输出 undefined , 只有变量声明被提升 , 变量初始化在后面
console.log(num); 
// 声明变量 , 并将变量初始化为 5 
var num = 5;

var num = 5; 操作其实是两步操作 , 先声明了变量 , 在为变量初始化了数值 5 ;

cpp 复制代码
var num;
num = 5;

变量提升 , 只将 变量声明 , 也就是 var num; 语句提升到了 当前作用域 的最前面 , num = 5; 初始化赋值操作 仍然在原来的位置 ;

预解析 变量提升 的效果相当于将 代码转为 :

cpp 复制代码
// 声明变量
var num;
// 输出 undefined , 只有变量声明被提升 , 变量初始化在后面
console.log(num); 
// 变量初始化赋值 5 
num = 5;

2、代码示例 - 变量预解析

下面的代码中的 JavaScript 代码 , 最终执行结果与下面的代码一致 ;

JavaScript 引擎 将

js 复制代码
// 输出 undefined , 只有变量声明被提升 , 变量初始化在后面
console.log(num); 
// 声明变量 , 并将变量初始化为 5 
var num = 5;

预解析为 :

js 复制代码
// 声明变量
var num;
// 输出 undefined , 只有变量声明被提升 , 变量初始化在后面
console.log(num); 
// 变量初始化赋值 5 
num = 5;

代码示例 :

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <!-- 设置 meta 视口标签 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no,maximum-scale=1.0,minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>JavaScript</title>
    <style></style>
    <script>
        // 预解析

        // 变量预解析 - 变量提升
        // 输出 undefined , 只有变量声明被提升 , 变量初始化在后面
        console.log(num);
        // 声明变量 , 并将变量初始化为 5 
        var num = 5;
    </script>
</head>

<body>
</body>

</html>

执行结果 :

三、函数预解析


1、函数预解析 - 函数提升

函数预解析 又称为 " 函数提升 " , 与 变量提升类似 , 使用 function 关键字 的 函数声明 也会被提升到它们所在的作用域的顶部 , 因此可以 在函数声明之前 调用该函数 ;

在下面的代码中 , 先调用了 hello 函数 , 再使用 function 关键字 声明函数 ,

js 复制代码
        hello();

        function hello() {
            console.log("Hello");
        }

在 JavaScript 引擎 进行 预解析时 , 函数预解析 就是将 function 关键字声明的函数 , 提升到 作用域最顶端 , 因此 可以在 函数执行前调用 该函数 ;

函数预解析 后的 代码效果如下 , 调用 hello 函数 , 成功执行该函数 , 这是因为 函数预解析 过程将 函数提升到了 作用域最顶端 ;

js 复制代码
		function hello() {
            console.log("Hello");
        }
        hello();

2、代码示例 - 函数预解析

代码示例 :

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <!-- 设置 meta 视口标签 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no,maximum-scale=1.0,minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>JavaScript</title>
    <style></style>
    <script>
        // 预解析

        // 函数预解析 - 函数提升

        // 输出 Hello , 函数声明提升到 作用域最顶部
        hello();

        // 函数预解析
        function hello() {
            console.log("Hello");
        }
    </script>
</head>

<body>
</body>

</html>

执行结果 :

四、函数表达式预解析


1、函数表达式预解析

函数表达式 的 本质是一个 变量 , 只是将 函数 赋值给了 变量 ;

由于 变量预解析 时 , 只是将 var 关键字的 变量声明 提升到了 作用域的最顶端 , 变量的 初始化 仍然在原地 ;

此时 通过该 变量 调用函数 , 肯定会报错 , 因为 函数此时没有赋值给 该变量 ;

在下面的代码中 , var fun 是一个变量 , 因此这里只进行 变量的提升 ,

js 复制代码
        // 报错 : Uncaught TypeError: fun is not a function
        fun();

        // 函数预解析
        var fun = function hello() {
            console.log("Hello");
        }

变量提升后的效果如下 :

js 复制代码
		// 函数提升
		var fun;
		
        // 报错 : Uncaught TypeError: fun is not a function
        fun();

        // 将 函数表达式 赋值给 fun 变量
        fun = function hello() {
            console.log("Hello");
        }

上述代码执行后 , 就会报错 Uncaught TypeError: fun is not a function ;

2、代码示例 - 函数表达式预解析

代码示例 :

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <!-- 设置 meta 视口标签 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no,maximum-scale=1.0,minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>JavaScript</title>
    <style></style>
    <script>
        // 预解析

        // 函数表达式 预解析情况

        // 报错 : Uncaught TypeError: fun is not a function
        fun();

        // 函数预解析
        var fun = function hello() {
            console.log("Hello");
        }
    </script>
</head>

<body>
</body>

</html>

执行结果 :

相关推荐
鸭梨大大大几秒前
Spring Web MVC入门
前端·spring·mvc
你的人类朋友几秒前
MQTT协议是用来做什么的?此协议常用的概念有哪些?
javascript·后端·node.js
吃没吃3 分钟前
vue2.6-源码学习-Vue 初始化流程分析 (src/core/instance/init.js)
前端
XH2764 分钟前
Android Room用法详解
前端
霍徵琅18 分钟前
Groovy语言的物联网
开发语言·后端·golang
木木黄木木1 小时前
css炫酷的3D水波纹文字效果实现详解
前端·css·3d
独好紫罗兰1 小时前
洛谷题单3-P1420 最长连号-python-流程图重构
开发语言·python·算法
美食制作家1 小时前
【无标题】Threejs第一个3D场景
javascript·three
kingmax542120081 小时前
深入解析:使用Python爬取Bilibili视频
开发语言·python·音视频
申雪菱1 小时前
Scheme语言的数据挖掘
开发语言·后端·golang