news 2026/4/6 6:58:02

一篇文章了解 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/4/3 14:29:06

TensorFlow-GPU安装全指南:版本匹配与实操步骤

TensorFlow-GPU 安装实战:从驱动到成功调用 GPU 的完整路径 在深度学习的世界里,没有比“明明有显卡却用不了 GPU”更让人抓狂的事了。你跑 tf.config.list_physical_devices(GPU),结果返回一个空列表;你查了教程、重装了十遍&am…

作者头像 李华
网站建设 2026/4/4 12:01:24

BGE-Large-zh-v1.5模型部署:从理念认知到场景应用的全流程指南

BGE-Large-zh-v1.5模型部署:从理念认知到场景应用的全流程指南 【免费下载链接】bge-large-zh-v1.5 项目地址: https://ai.gitcode.com/hf_mirrors/ai-gitcode/bge-large-zh-v1.5 当你面对BGE-Large-zh-v1.5这个强大的中文文本嵌入模型时,是否曾…

作者头像 李华
网站建设 2026/3/29 18:25:07

NVIDIA驱动深度配置实战:性能调优的进阶解析

NVIDIA驱动深度配置实战:性能调优的进阶解析 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 在图形性能优化的战场上,NVIDIA显卡用户往往受限于官方控制面板的功能边界。然而&am…

作者头像 李华
网站建设 2026/4/1 6:58:05

LobeChat能否收集改进建议?产品迭代依据

LobeChat 的产品迭代逻辑:如何通过架构设计实现持续进化 在大语言模型(LLM)应用井喷的今天,用户早已不再满足于“能对话”的AI工具——他们需要的是稳定、可定制、安全且能融入工作流的智能助手。尽管 OpenAI 的 ChatGPT 树立了交…

作者头像 李华
网站建设 2026/4/3 19:10:46

百度网盘提取码智能获取方案

当你面对百度网盘分享链接时,是否曾经因为找不到提取码而陷入困境?在信息爆炸的时代,资源获取效率直接影响着我们的学习和工作效率。传统的手动搜索方式不仅耗时耗力,还常常因为页面跳转而打乱工作节奏。现在,这一切都…

作者头像 李华
网站建设 2026/3/26 5:56:57

飞书文档批量导出神器:三步搞定知识库迁移

飞书文档批量导出神器:三步搞定知识库迁移 【免费下载链接】feishu-doc-export 项目地址: https://gitcode.com/gh_mirrors/fe/feishu-doc-export 还在为飞书文档迁移而烦恼吗?面对成百上千的文档,手动下载不仅耗时耗力,还…

作者头像 李华