【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>

执行结果 :

相关推荐
面试鸭2 分钟前
离谱!买个人信息买到网安公司头上???
java·开发语言·职场和发展
小白学大数据2 分钟前
JavaScript重定向对网络爬虫的影响及处理
开发语言·javascript·数据库·爬虫
Python大数据分析@6 分钟前
python操作CSV和excel,如何来做?
开发语言·python·excel
qq_3901617711 分钟前
防抖函数--应用场景及示例
前端·javascript
上海_彭彭31 分钟前
【提效工具开发】Python功能模块执行和 SQL 执行 需求整理
开发语言·python·sql·测试工具·element
3345543239 分钟前
element动态表头合并表格
开发语言·javascript·ecmascript
John.liu_Test41 分钟前
js下载excel示例demo
前端·javascript·excel
沈询-阿里43 分钟前
java-智能识别车牌号_基于spring ai和开源国产大模型_qwen vl
java·开发语言
Yaml41 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事1 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro