JavaScript 函数与变量作用
一、为什么要学习函数?
浏览器执行代码时,需要你给出非常详细的指令。如果所有逻辑都写成零散的语句,成百上千行代码会变得难以维护和复用。
函数、方法和对象,正是解决这一问题的核心工具。它们能帮你:
- 组织代码结构,让逻辑更清晰
- 复用重复代码,减少冗余
- 控制执行时机,只在需要时运行代码
二、函数基础:定义与调用
1. 什么是函数?
函数是一组语句的集合,用于执行特定任务。它有两个核心优势:
- 代码复用:把重复执行的逻辑封装起来,避免复制粘贴相同代码
- 延迟执行:函数内的代码不会随页面加载自动执行,只有被 “调用” 时才会运行
2. 函数的声明与调用
(1)基础语法结构
javascript
运行
// 函数声明:定义一个简单的打招呼函数
function sayHello() {
// 函数体:执行任务的代码块
document.write('Hello!');
}
// 函数调用:触发函数执行
sayHello(); // 控制台/页面输出:Hello!
function:关键字,用于声明函数sayHello:函数名,用于后续调用(需见名知意)():参数列表(无参数时为空){}:函数体,包含要执行的代码
(2)带参数的函数
当函数需要外部数据才能完成任务时,可以通过形参接收输入:
javascript
运行
// 声明带形参的函数:计算矩形面积
function getArea(width, height) {
// 形参 width 和 height 在函数内的行为和变量完全一致
return width * height;
}
// 调用函数时传入实参:3和5分别对应width和height
let wallArea = getArea(3, 5);
console.log(wallArea); // 输出:15
- 形参:函数声明时括号内的变量,仅在函数内部有效
- 实参:调用函数时传入的具体值,会被赋值给对应的形参
(3)带返回值的函数
函数执行后,可以通过 return 关键字将结果返回给调用它的代码:
javascript
运行
function calculateArea(width, height) {
// 函数内部定义变量存储计算结果
let area = width * height;
// return 关键字:返回结果,并立即结束函数执行
return area;
}
// 用变量接收函数的返回值
let wallOne = calculateArea(3, 5); // 结果:15
let wallTwo = calculateArea(8, 5); // 结果:40
console.log(wallOne, wallTwo); // 输出:15 40
⚠️ 注意:return 执行后,函数会立即停止,后续代码不会被执行。
三、函数进阶:表达式与匿名函数
1. 函数声明 vs 函数表达式
(1)函数声明(Function Declaration)
我们前面写的 function area() {} 就是函数声明,它的特点是:
- 有明确的函数名
- 存在函数提升:可以在声明之前调用
javascript
运行
// 声明函数
function area(width, height) {
return width * height;
}
// 可以在声明前调用(提升特性)
let size = area(3, 4);
console.log(size); // 输出:12
(2)函数表达式(Function Expression)
将函数赋值给变量,这种写法称为函数表达式。如果省略函数名,就是匿名函数:
javascript
运行
// 匿名函数表达式:函数没有名字,存储在变量area中
let area = function(width, height) {
return width * height;
};
// 调用方式和普通函数一致
let size = area(3, 4);
console.log(size); // 输出:12
⚠️ 注意:函数表达式没有提升特性,必须先声明再调用。
2. 立即调用函数表达式(IIFE)
如果希望函数定义后立即执行一次,可以使用 IIFE(Immediately Invoked Function Expression,读作 “iffy”):
javascript
运行
// IIFE 写法:匿名函数 + 立即执行括号
let area = (function() {
let width = 3;
let height = 2;
return width * height;
})();
console.log(area); // 输出:6
核心作用:
- 隔离作用域:IIFE 内部的变量不会污染全局环境
- 一次性执行:适合初始化、配置等只需要运行一次的逻辑
- 避免命名冲突:多个脚本文件中同名变量互不影响(jQuery 早期广泛使用这种模式)
四、变量作用域:局部与全局
变量的声明位置决定了它的作用域(可访问范围),这是 JS 中最容易踩坑的知识点之一。
1. 局部变量(函数作用域)
在函数内部用 var/let/const 声明的变量,只能在该函数内部访问,称为局部变量:
javascript
运行
function getArea(width, height) {
// 局部变量:仅在函数内部有效
let area = width * height;
return area;
}
getArea(3, 2);
console.log(area); // 报错:area is not defined(外部无法访问)
- 局部变量在函数执行时创建,执行结束后立即销毁
- 不同函数内的同名局部变量不会冲突
2. 全局变量
在函数外部声明的变量,或声明时省略 var/let/const 的变量,会成为全局变量:
javascript
运行
// 全局变量:脚本任何地方都能访问
let wallSize = 0;
function getArea(width, height) {
wallSize = width * height; // 直接修改全局变量
return wallSize;
}
getArea(3, 2);
console.log(wallSize); // 输出:6(外部可以访问)
⚠️ 全局变量的风险:
- 内存占用:页面加载期间一直驻留内存,影响性能
- 命名冲突:多个脚本中同名全局变量会相互覆盖
- 调试困难:全局变量的修改难以追踪
3. 作用域最佳实践
- 优先使用局部变量,减少全局变量声明
- 必要时用 IIFE 封装代码,隔离作用域
- 声明变量时必须加
let/const,避免意外创建全局变量
五、实战:用函数封装一个面积计算器
结合前面的知识点,我们写一个完整的面积计算器,支持矩形和圆形:
javascript
运行
// 1. 矩形面积计算(带参数和返回值)
function calculateRectangleArea(width, height) {
if (width <= 0 || height <= 0) {
return '错误:宽和高必须大于0';
}
return width * height;
}
// 2. 圆形面积计算(带参数和返回值)
function calculateCircleArea(radius) {
if (radius <= 0) {
return '错误:半径必须大于0';
}
return Math.PI * radius * radius;
}
// 3. 用IIFE封装初始化逻辑(一次性执行)
(function() {
let wallWidth = 4;
let wallHeight = 5;
let wallArea = calculateRectangleArea(wallWidth, wallHeight);
console.log(`墙的面积:${wallArea} 平方米`);
let circleRadius = 3;
let circleArea = calculateCircleArea(circleRadius);
console.log(`圆形的面积:${circleArea.toFixed(2)} 平方米`);
})();
运行结果:
plaintext
墙的面积:20 平方米
圆形的面积:28.27 平方米
六、总结与进阶方向
核心知识点回顾
表格
| 概念 | 关键要点 |
|---|---|
| 函数声明 | 用 function 关键字定义,支持提升,可在声明前调用 |
| 函数表达式 | 函数赋值给变量,无提升,必须先声明再调用 |
| 形参 / 实参 | 形参是占位符,实参是实际传入的值 |
return |
返回结果并结束函数,无 return 时返回 undefined |
| 作用域 | 局部变量仅函数内有效,全局变量作用于整个脚本 |
| IIFE | 匿名函数立即执行,用于隔离作用域 |
进阶学习方向
- 箭头函数:ES6 新增的
() => {}语法,更简洁的函数写法 - 闭包:函数嵌套时,内部函数访问外部函数变量的特性
- 回调函数:将函数作为参数传递,实现异步逻辑(如事件监听)
- 函数柯里化:将多参数函数拆分为多个单参数函数,实现参数复用
💡 写在最后:函数是 JS 的 “第一公民”,从简单的工具函数到复杂的业务逻辑,几乎所有 JS 代码都离不开函数。理解函数的声明、调用、作用域和执行机制,是你从入门到进阶的必经之路。
更多推荐

所有评论(0)