深入理解 JavaScript 函数
🎯 引言
你将全面掌握 JavaScript 函数的各种用法,理解函数的创建、调用及执行过程,搞明白函数作用域、闭包和参数传递等重要知识点。掌握这些内容后,你能写出更简洁、高效的代码,避免常见陷阱,提升前端开发能力。
🔍 函数是什么?从零开始理解
JS 函数,本质上是一段可重复执行的代码块。它帮我们把复杂的任务拆分成小块,方便调用和管理。就像厨房里的厨师,函数是完成某道菜的步骤,厨师按照步骤来做菜,函数就按代码执行任务。
常见的创建函数方式有三种:
// 函数声明
function greet(name) {
return '你好,' + name + '!';
}
// 函数表达式
const greet2 = function (name) {
return '你好,' + name + '!';
};
// 箭头函数(ES6,不在本篇重点)
const greet3 = name => '你好,' + name + '!';
🧩 函数的调用和返回
调用函数就是让它执行里面的代码,比如:
console.log(greet('小明'));
这句代码会输出“你好,小明!”。函数执行完后,遇到 return 会把结果返回给调用者。如果没有返回值,默认返回 undefined。
函数也可以不带参数,比如:
function sayHi() {
console.log('嗨!');
}
sayHi();
🧠 作用域与函数作用域
作用域决定了变量在哪里有效。JavaScript 函数自带“作用域”,函数内部定义的变量外面访问不到。
function foo() {
let message = 'Hello';
console.log(message);
}
foo();
console.log(message); // 报错,message 未定义
函数执行时,会形成一个独立的作用域,里面的变量不会影响外面,外面也访问不到函数内部变量。
🔄 参数与实参:传值还是传引用?
JS 函数传递参数时,有两个重要概念:
- 基本类型参数(比如数字、字符串、布尔)是传值的,函数内修改不会影响外面变量。
- 引用类型参数(比如对象、数组)是传引用的,函数内修改会影响外部。
举个例子:
function changeNumber(num) {
num = 100;
}
let a = 50;
changeNumber(a);
console.log(a); // 50,外部没变
function changeObj(obj) {
obj.name = '小明';
}
let person = { name: '小红' };
changeObj(person);
console.log(person.name); // 小明
🔒 闭包:函数的神奇力量
闭包是 JS 函数最强大的特点之一。简单来说,函数可以“记住”创建它时外部的变量,即使外部函数已经执行完。
function outer() {
let count = 0;
return function inner() {
count++;
console.log('计数器:', count);
};
}
const counter = outer();
counter(); // 计数器:1
counter(); // 计数器:2
这里 inner 函数访问了 outer 函数的变量 count,并且 count 信息被保留下来,形成闭包。
闭包非常适合做计数器、缓存数据这样的场景。
📝 函数声明 vs 函数表达式
两者看起来很像,但有个重要区别是“提升”(hoisting)。
函数声明会被 JS 解析器提前加载,你可以在声明之前调用。
sayHello();
function sayHello() {
console.log('Hello');
}
函数表达式则不会提升,必须先定义再调用,否则报错。
sayHi(); // 报错
const sayHi = function () {
console.log('Hi');
};
💡 小提示:函数默认参数模拟
在 JavaScript 中,如果函数调用时没有传入某个参数,它的值会是 undefined。可以通过在函数内部手动检查参数是否传入,并设置默认值:
function greet(name) {
if (typeof name === 'undefined') {
name = '朋友';
}
return '你好,' + name + '!';
}
🧾 小节总结
- JS 函数是封装可复用代码的基本单位,理解函数声明、调用、参数传递很关键。
- 函数作用域保护变量,闭包让函数“记住”外部变量,是解决复杂业务的利器。
- 注意函数声明和函数表达式的提升差异,合理利用默认参数和闭包提高代码质量。
❓ 知识问答(Q&A)
Q:函数表达式和函数声明有什么区别?
A:函数声明会被提升,可以先调用后声明;函数表达式不会提升,必须先定义后调用。
Q:闭包是什么,有什么作用?
A:闭包是函数“记住”定义时的外部变量。它能让函数访问并操作外部函数的局部变量,常用于数据缓存和私有变量。
🧪 小练习
练习1:写一个函数,接收两个参数,返回它们的乘积。调用这个函数并打印结果。
function multiply(a, b) {
// 实现代码
}
console.log(multiply(3, 5)); // 期望输出 15
练习2:利用闭包写一个计数器函数,调用它每次数字加 1,并返回当前计数。
function createCounter() {
// 返回一个内部函数,实现计数功能
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
🎉 恭喜你已经掌握 JS 函数的声明、调用、作用域、参数传递和闭包等核心技能啦!祝你前端学习之路顺利!
