JavaScript函数声明大比拼
🎭 JavaScript函数声明大比拼:var vs function
🔍 两种声明方式对比
⭐ 根本区别解析
1️⃣ 提升机制(Hoisting)- 核心区别!
// 使用前调用
sayHi(); // ✅ 正常工作:"你好!"
speak(); // ❌ 错误:speak is not a function// 声明
function sayHi() {console.log("你好!");
}var speak = function() {console.log("你好呀!");
};
💡 形象比喻:
- function声明像电梯直达顶层 - 整个函数体被提升
- var声明像占座位 - 只有名字被提升,内容还在原地等待
🎮 趣味实例:代码执行顺序游戏
🌟 两种方式的特性对比表
特性 | function声明 | var声明函数表达式 |
---|---|---|
提升方式 | 完整提升 ⬆️ | 只提升变量名 ⬆️ |
可在声明前调用 | ✅ 是 | ❌ 否 |
可匿名 | ❌ 否 | ✅ 是 |
可条件声明* | ❌ 不推荐 | ✅ 可以 |
可重新赋值 | ❌ 否 | ✅ 可以 |
适合递归 | ✅ 更好 | ⚠️ 需小心 |
*注:在严格模式下,条件内的function声明行为在不同浏览器有差异
🎯 有趣场景对比
场景一:函数重写
// var声明的灵活性
var calculateArea;if (isCircle) {calculateArea = function(r) { return Math.PI * r * r; };
} else {calculateArea = function(w, h) { return w * h; };
}// function声明不建议这样用(会有问题)
if (isCircle) {function calculateArea(r) { return Math.PI * r * r; } // ⚠️危险
} else {function calculateArea(w, h) { return w * h; } // ⚠️危险
}
场景二:递归与函数名引用
// ✅ function声明 - 内部可靠地引用自身
function factorial(n) {return n <= 1 ? 1 : n * factorial(n-1); // 稳定引用
}// ⚠️ var声明 - 如果变量被重新赋值,递归会断开
var factorial = function(n) {return n <= 1 ? 1 : n * factorial(n-1); // 可能断开
};// 更安全的函数表达式写法
var factorial = function fact(n) { // 使用命名函数表达式return n <= 1 ? 1 : n * fact(n-1); // 稳定引用
};
📊 选择指南:何时用哪种声明方式?
🎪 趣味理解
function声明像一个正式公职人员:
- 在代码的"城市"中有固定位置 📌
- 从代码执行的"一开始"就在岗位上 🏢
- 名字和职责都明确且不可更改 📋
var声明函数表达式像一个自由职业者:
- 先占位,后决定具体做什么 🎯
- 可以根据条件改变工作内容 🔄
- 更加灵活但初始化需要时间 ⏱️
🚨 常见陷阱与避坑指南
// 陷阱1: var声明提升但赋值不提升
console.log(sum(1, 2)); // ❌ 错误: sum is not a function
var sum = function(a, b) { return a + b; };// 陷阱2: 条件内的function声明(不同浏览器行为不一)
if (true) {function danger() { return "版本A"; }
} else {function danger() { return "版本B"; }
}
console.log(danger()); // ⚠️ 结果不确定!
💡 现代JavaScript的最佳实践
📚 总结
- ⚠️ 关键区别: function声明完整提升,var声明只提升变量名
- 🔑 function优势: 代码清晰,可靠的递归,声明前可用
- 🔑 var函数表达式优势: 条件赋值,灵活性高,可匿名
- 💪 现代实践: 主要函数用function声明,简短回调考虑箭头函数,使用const/let声明而非var
在不同场景选择正确的声明方式,可以让你的代码更加清晰可靠!