当前位置: 首页 > news >正文

JavaScript函数声明大比拼

🎭 JavaScript函数声明大比拼:var vs function

🔍 两种声明方式对比

JavaScript函数声明方式
function关键字声明\nfunction foo() {}
var变量声明函数表达式\nvar foo = function() {}
函数提升\n(整体提升到作用域顶部)
声明简洁
命名清晰
变量提升\n(仅变量名提升,赋值不提升)
灵活性高\n(可条件赋值)
可立即重新赋值

⭐ 根本区别解析

1️⃣ 提升机制(Hoisting)- 核心区别

// 使用前调用
sayHi();  // ✅ 正常工作:"你好!"
speak();  // ❌ 错误:speak is not a function// 声明
function sayHi() {console.log("你好!");
}var speak = function() {console.log("你好呀!");
};

💡 形象比喻:

  • function声明像电梯直达顶层 - 整个函数体被提升
  • var声明像占座位 - 只有名字被提升,内容还在原地等待

🎮 趣味实例:代码执行顺序游戏

var声明提升
只有var test被提升
并初始化为undefined
var test = function() {...}
函数体部分在原位置执行
不能在赋值前调用
function声明提升
整个函数体被提升
可以在声明前调用
function test() {...}
代码执行顺序
第2步: 提升所有声明
第1步: JS引擎扫描代码
第3步: 执行代码

🌟 两种方式的特性对比表

特性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声明函数表达式
优先简洁还是灵活?

🎪 趣味理解

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的最佳实践

现代JavaScript推荐
主要函数使用
function声明
使用const/let替代var
const calculate = function(){}
箭头函数用于简短回调
数组方法等

📚 总结

  • ⚠️ 关键区别: function声明完整提升,var声明只提升变量名
  • 🔑 function优势: 代码清晰,可靠的递归,声明前可用
  • 🔑 var函数表达式优势: 条件赋值,灵活性高,可匿名
  • 💪 现代实践: 主要函数用function声明,简短回调考虑箭头函数,使用const/let声明而非var

在不同场景选择正确的声明方式,可以让你的代码更加清晰可靠!

http://www.xdnf.cn/news/214741.html

相关文章:

  • yolov8使用
  • 10 基于Gazebo和Rviz实现导航仿真,包括SLAM建图,地图服务,机器人定位,路径规划
  • BIM(建筑信息模型)与GIS(地理信息系统)的融合的技术框架、实现路径与应用场景
  • 【MCP Node.js SDK 全栈进阶指南】高级篇(2):MCP高性能服务优化
  • MCP 协议 ——AI 世界的 “USB-C 接口”:从认知到实践的全面指南
  • 源码角度分析 sync.map
  • Silvaco仿真中victory process的蒙特卡洛(Monte Carlo)离子注入
  • [4-06-09].第10节:自动配置- 分析@SpringBootApplication启动类
  • github使用记录
  • Redis分布式锁使用以及对接支付宝,paypal,strip跨境支付
  • 第十六届蓝桥杯大赛网安组--几道简单题的WP
  • HTTP协议重定向及交互
  • 运放参数汇总
  • mac word接入deepseek
  • LVGL -窗口操作
  • Linux/AndroidOS中进程间的通信线程间的同步 - 管道和FIFO
  • 【C++编程入门】:基本语法
  • Java 多线程基础:Thread 类详解
  • 云数据中心整体规划方案PPT(113页)
  • VIT(ICLR2021)
  • foc控制 - clarke变换和park变换
  • 【后端】【Docker】 Docker 动态代理 取消代理完整脚本合集(Ubuntu)
  • 内网服务器映射到公网上怎么做?网络将内网服务转换到公网上
  • 学习基本宠物美容
  • 零基础实现把知识库接到聆思CSK6大模型开发板上
  • 请简述一下什么是 Kotlin?它有哪些特性?
  • C++ 红黑树
  • 第14讲:科研图表的导出与排版艺术——高质量 PDF、TIFF 输出与投稿规范全攻略!
  • Java 基础--运算符全解析
  • Ubuntu搭建 Nginx以及Keepalived 实现 主备