2026/1/19 16:12:56
网站建设
项目流程
网站模板 安全吗,杭州产品设计公司有哪些,wordpress 熊掌号插件,苏州地产网站建设函数与变量的优先级#xff1a;搞懂这3个核心场景#xff0c;再也不踩坑
在 JavaScript 开发中#xff0c;我们经常会遇到这样的困惑#xff1a;当函数和变量同名时#xff0c;到底谁会被优先访问#xff1f;为什么有时候打印的是函数#xff0c;有时候却是变量值#…函数与变量的优先级搞懂这3个核心场景再也不踩坑在 JavaScript 开发中我们经常会遇到这样的困惑当函数和变量同名时到底谁会被优先访问为什么有时候打印的是函数有时候却是变量值其实这背后藏着 JS 引擎的执行机制——变量提升与函数提升的优先级规则。今天这篇文章就从「提升机制的本质」出发通过 3 个核心场景的代码案例帮你彻底搞懂函数与变量的优先级逻辑从此避开这类基础却致命的 bugs。一、先理清变量提升 vs 函数提升在聊优先级之前我们必须先明确两个基础概念变量提升Hoisting和函数提升。这是 JS 引擎在执行代码前的「预编译」阶段会做的核心操作。简单来说变量提升var 声明的变量会被提升到当前作用域顶部但仅提升声明不提升赋值值为 undefinedlet/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 引擎的预编译和执行过程预编译阶段先提升函数声明 function a() {}再提升 var a但由于 a 已经被函数声明占用var a 的提升会被忽略不会重复声明。此时作用域顶部的 a 是函数 a() {}。执行阶段第一行 console.log(a)访问的是提升后的函数 a所以输出函数体。执行 var a 10; 时是对已存在的 a 进行赋值将函数覆盖为 10。第二行 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拆解过程预编译阶段提升两个 var b 声明由于重复声明仅保留一个此时 b 的值为 undefined。执行阶段第一行 console.log(b)输出 undefined。执行 var b function(){}将 b 赋值为函数。执行 var b 20将 b 赋值为 20覆盖函数。第二行 console.log(b)输出 20。这里要注意函数表达式的函数体不会被提升所以第一次打印的是 undefined而不是函数——这是和函数声明的核心区别。三、总结优先级核心规则表格梳理为了方便记忆用表格汇总不同场景下的优先级顺序从高到低场景优先级顺序核心结论函数声明 vs var 变量函数声明 var 变量声明同名时预编译后先存在函数var 声明被忽略赋值后覆盖函数函数声明 vs let/const 变量let/const 暂时性死区 函数声明同名时声明前访问报错声明后函数无法重复定义函数表达式 vs 变量任意声明同变量优先级无函数提升优势函数表达式仅提升变量声明值为 undefined赋值后覆盖四、实战避坑建议理解了优先级规则后在实际开发中可以通过以下几点避免踩坑避免函数和变量同名这是最根本的解决办法尽量让标识符具有唯一性减少优先级竞争。优先使用 let/const 替代 varlet/const 的暂时性死区可以避免“声明前访问”的bug同时不允许重复声明让代码更严谨。区分函数声明和函数表达式如果需要函数在声明前被访问用函数声明如果需要控制函数的可用时机用函数表达式配合 var/let 声明。养成“先声明后使用”的习惯无论变量还是函数尽量在作用域顶部声明避免依赖提升机制让代码可读性更强。五、最后案例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 暂时性死区优于函数声明”这两个核心点再结合具体场景拆解就能轻松应对所有相关问题。