javascript 中多个同名函数声明会被后者覆盖,最终只有最后一个声明生效。这是因为 javascript 引擎在执行代码前会进行预解析(hoisting),将函数声明提升到作用域顶部,后出现的同名声明会直接替换先前的定义。

同名函数声明的覆盖机制是怎样的
同名函数声明遵循“后声明覆盖先声明”的原则。在同一个作用域内,无论函数声明出现在代码的哪个位置,引擎都会将其提升到当前作用域的顶部。如果存在多个同名声明,后面的声明会完全取代前面的声明,导致前面的声明失效。

function greet() {
console.log("Hello from first");
}
function greet() {
console.log("Hello from second");
}
greet(); // 输出: Hello from second
上述代码展示了两个同名函数 greet 的声明。尽管第一个函数先被定义,但第二个函数声明会覆盖它。因此,调用 greet() 时执行的是第二个函数的逻辑。这种行为在严格模式和非严格模式下均一致,是 JavaScript 函数提升特性的直接结果。
函数表达式与声明在命名冲突时有何不同
函数表达式不会发生提升覆盖,而是按顺序赋值。如果使用函数表达式(如 var、let 或 const 赋值),则不存在提升覆盖的问题,而是变量赋值的顺序问题。后赋值的表达式会覆盖先赋值的引用。

var greet = function() {
console.log("First expression");
};
var greet = function() {
console.log("Second expression");
};
greet(); // 输出: Second expression
这里使用 var 声明了两个同名变量 greet,分别指向不同的函数表达式。由于 var 允许重复声明,第二个赋值操作覆盖了第一个变量的值。这与函数声明的提升覆盖不同,函数表达式是在运行时按顺序执行的,没有提升阶段。若使用 let 或 const,重复声明会导致语法错误,从而避免此类覆盖行为。
嵌套作用域中的同名函数如何处理
在嵌套作用域中,内部作用域的函数声明会遮蔽外部作用域的同名函数。当在内部作用域中调用该函数时,优先执行内部定义的版本;而在外部作用域中调用时,仍执行外部定义的版本。这种遮蔽效应遵循词法作用域规则,不影响外部作用域的定义。
function outer() {
console.log("Outer function");
function inner() {
console.log("Inner function");
}
function outer() {
console.log("Overridden Outer");
}
outer(); // 输出: Overridden Outer
}
outer(); // 输出: Overridden Outer
在 outer 函数内部,再次声明了同名函数 outer。根据提升规则,内部的 outer 声明会覆盖外部的 outer 声明。因此,在内部调用 outer() 时,执行的是被覆盖后的版本。而在全局作用域中调用 outer() 时,同样执行被覆盖后的版本,因为内部声明提升了并覆盖了全局的同名函数。这种遮蔽效应在嵌套作用域中尤为明显,需注意作用域链的影响。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











