news 2026/8/28 5:54:31

一篇文章了解 JavaScript 开发中函数与变量的优先级

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一篇文章了解 JavaScript 开发中函数与变量的优先级

函数与变量的优先级:搞懂这3个核心场景,再也不踩坑

在 JavaScript 开发中,我们经常会遇到这样的困惑:当函数和变量同名时,到底谁会被优先访问?为什么有时候打印的是函数,有时候却是变量值?其实这背后藏着 JS 引擎的执行机制——变量提升与函数提升的优先级规则。

今天这篇文章,就从「提升机制的本质」出发,通过 3 个核心场景的代码案例,帮你彻底搞懂函数与变量的优先级逻辑,从此避开这类基础却致命的 bugs。

一、先理清:变量提升 vs 函数提升

在聊优先级之前,我们必须先明确两个基础概念:变量提升(Hoisting)和函数提升。这是 JS 引擎在执行代码前的「预编译」阶段会做的核心操作。

简单来说:

  • 变量提升:var 声明的变量会被提升到当前作用域顶部,但仅提升声明,不提升赋值(值为 undefined);let/const 声明的变量也会提升,但存在「暂时性死区」,不能在声明前访问。
  • 函数提升:函数声明(function 关键字声明)会被完整提升到当前作用域顶部,包括函数体;而函数表达式(如 var fn = function(){})不会提升函数体,仅提升变量声明(同 var 变量)。

而函数与变量的优先级,核心就体现在「提升阶段的竞争」——谁在提升后更“靠前”,谁就会被优先访问。

二、3 个核心场景,吃透优先级规则

场景 1:函数声明 vs var 变量(同名)

先看一段经典代码:

console.log(a); // 输出:function a() {} var a = 10; function a() {} console.log(a); // 输出:10

为什么第一次打印的是函数,而不是 undefined 或 10?这就是优先级规则在起作用:函数声明的提升优先级高于 var 变量声明

拆解 JS 引擎的预编译和执行过程:

  1. 预编译阶段:先提升函数声明 function a() {},再提升 var a(但由于 a 已经被函数声明占用,var a 的提升会被忽略,不会重复声明)。此时作用域顶部的 a 是函数 a() {}。
  2. 执行阶段:第一行 console.log(a),访问的是提升后的函数 a,所以输出函数体。
  3. 执行 var a = 10; 时,是对已存在的 a 进行赋值,将函数覆盖为 10。
  4. 第二行 console.log(a),此时 a 已经是 10,所以输出 10。

注意:这里是「变量声明」被忽略,不是「赋值」被忽略。如果变量声明后有赋值操作,依然会覆盖函数。

场景 2:函数声明 vs let/const 变量(同名)

如果把 var 换成 let/const,情况会完全不同:

console.log(a); // 报错:Cannot access 'a' before initialization let a = 10; function a() {}

为什么会报错?因为 let/const 存在「暂时性死区(TDZ)」:

虽然 let/const 变量也会提升,但提升后会被置于暂时性死区中,在声明语句(let a = 10)执行前,任何访问都会报错。此时即使有同名的函数声明,也无法突破暂时性死区——let/const 的暂时性死区优先级高于函数提升

补充:如果函数声明在 let 声明之后,同样会报错,因为同名的 let 变量提升后占据了标识符,函数声明无法重复定义:

let a = 10; function a() {} // 报错:Identifier 'a' has already been declared

场景 3:函数表达式 vs 变量(同名)

函数表达式(如 var fn = function(){})本质上是「变量声明 + 函数赋值」,所以它的提升规则和 var 变量完全一致,优先级自然也和 var 变量相同(不存在函数声明的高优先级)。

看代码案例:

console.log(b); // 输出:undefined var b = function() { console.log('函数表达式'); }; var b = 20; console.log(b); // 输出:20

拆解过程:

  1. 预编译阶段:提升两个 var b 声明,由于重复声明,仅保留一个,此时 b 的值为 undefined。
  2. 执行阶段:第一行 console.log(b),输出 undefined。
  3. 执行 var b = function(){},将 b 赋值为函数。
  4. 执行 var b = 20,将 b 赋值为 20,覆盖函数。
  5. 第二行 console.log(b),输出 20。

这里要注意:函数表达式的函数体不会被提升,所以第一次打印的是 undefined,而不是函数——这是和函数声明的核心区别。

三、总结:优先级核心规则(表格梳理)

为了方便记忆,用表格汇总不同场景下的优先级顺序(从高到低):

场景优先级顺序核心结论
函数声明 vs var 变量函数声明 > var 变量声明同名时,预编译后先存在函数,var 声明被忽略,赋值后覆盖函数
函数声明 vs let/const 变量let/const 暂时性死区 > 函数声明同名时,声明前访问报错;声明后函数无法重复定义
函数表达式 vs 变量(任意声明)同变量优先级(无函数提升优势)函数表达式仅提升变量声明,值为 undefined,赋值后覆盖

四、实战避坑建议

理解了优先级规则后,在实际开发中可以通过以下几点避免踩坑:

  1. 避免函数和变量同名:这是最根本的解决办法,尽量让标识符具有唯一性,减少优先级竞争。
  2. 优先使用 let/const 替代 var:let/const 的暂时性死区可以避免“声明前访问”的bug,同时不允许重复声明,让代码更严谨。
  3. 区分函数声明和函数表达式:如果需要函数在声明前被访问,用函数声明;如果需要控制函数的可用时机,用函数表达式(配合 var/let 声明)。
  4. 养成“先声明后使用”的习惯:无论变量还是函数,尽量在作用域顶部声明,避免依赖提升机制,让代码可读性更强。

五、最后案例

console.log(c); var c = 30; function c() { console.log('c1'); } var c = function() { console.log('c2'); }; console.log(c);

核心提示:结合场景 1 和场景 3 的规则,拆解预编译和执行过程。

总结一下:函数与变量的优先级,本质是「提升机制的竞争」。记住“函数声明优于 var 变量声明,let/const 暂时性死区优于函数声明”这两个核心点,再结合具体场景拆解,就能轻松应对所有相关问题。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/28 18:37:08

【MediaPipe的手势识别系统】

上图先 import sys import cv2 import logging import mediapipe as mp import numpy as np from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QHBoxLayout, QWidget, QTextEdit, QPushButton from PyQt5.QtGui import QImage, QPixmap, QFont f…

作者头像 李华
网站建设 2026/8/28 19:09:59

HiveSQL 中的集合运算详解

在大数据分析过程中,整合多源数据的需求十分常见,此时集合运算发挥着关键作用。本文将重点介绍HiveSQL中的集合运算方法,助力数据分析师高效完成复杂的数据整合工作。为什么需要集合运算?假设你手头有来自多个业务系统的用户数据&…

作者头像 李华
网站建设 2026/8/29 2:44:26

LobeChat能否实现AI织布工?非遗技艺传承与现代时尚融合设计

LobeChat能否实现AI织布工?非遗技艺传承与现代时尚融合设计 在苏州博物馆的一角,一位年轻设计师正对着一块清代云锦残片沉思。她想从中提取纹样用于新中式礼服设计,却苦于无法准确理解那些繁复图案背后的文化语义。如果此刻有个懂历史、会审美…

作者头像 李华
网站建设 2026/8/28 15:57:20

窗口置顶神器:3个简单技巧让重要窗口永不消失

窗口置顶神器:3个简单技巧让重要窗口永不消失 【免费下载链接】AlwaysOnTop Make a Windows application always run on top 项目地址: https://gitcode.com/gh_mirrors/al/AlwaysOnTop AlwaysOnTop是一款专为Windows系统设计的窗口置顶工具,能够…

作者头像 李华
网站建设 2026/8/28 21:43:48

NVIDIA显卡性能调优终极指南:解锁隐藏设置与完整解决方案

NVIDIA显卡性能调优终极指南:解锁隐藏设置与完整解决方案 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 想要彻底释放NVIDIA显卡的潜能吗?许多用户可能不知道,官方驱…

作者头像 李华
网站建设 2026/8/22 22:24:11

最强AI生图工具NanoBanana-Pro玩法合集:释放创作潜力的无限可能

随着 人工智能 技术的不断突破,图像生成模型的功能已经远远超出了传统的想象,尤其是最近备受瞩目的 NanoBanana-Pro。作为一款新一代 AI图像生成工具,NanoBanana-Pro 不仅能够快速生成高质量的图像,还具备了强大的 创作自由度 和 …

作者头像 李华