JavaScript函数定义知识点汇总
编程小白也能理解的详细解释与实例
一、什么是函数?
函数是JavaScript中的基本构建块之一,它是一段可重复使用的代码块,用于执行特定任务。
为什么需要函数?
- 代码复用:避免重复编写相同代码
- 模块化:将复杂任务分解为小任务
- 可维护性:修改一处即可影响所有使用该函数的地方
- 抽象:隐藏实现细节,只暴露接口
💡 可以把函数想象成一个”黑盒子”:你给它输入(参数),它进行处理,然后输出结果(返回值)。你不需要知道内部如何工作,只需要知道如何使用它。
二、定义函数的四种方式
1. 函数声明
最常用的定义方式:
function 函数名(参数) {
// 函数体
return 结果; // 可选
}
// 函数体
return 结果; // 可选
}
2. 函数表达式
将函数赋值给变量:
const 变量名 = function(参数) {
// 函数体
};
// 函数体
};
3. 箭头函数 (ES6+)
简洁的语法,尤其适合短函数:
const 变量名 = (参数) => {
// 函数体
};
// 单参数可省略括号
const 平方 = x => x * x;
// 无参数需要空括号
const 问候 = () => “你好!”;
// 函数体
};
// 单参数可省略括号
const 平方 = x => x * x;
// 无参数需要空括号
const 问候 = () => “你好!”;
4. Function构造函数
不常用,主要用于动态创建函数:
const 相加 = new Function(‘a’, ‘b’, ‘return a + b;’);
⚠️ 注意:函数声明有提升特性(可以在定义前调用),而函数表达式和箭头函数没有。
三、函数参数详解
1. 形参与实参
形参:函数定义时声明的参数
实参:函数调用时传入的实际值
function greet(name) { // name是形参
console.log(`你好, ${name}!`);
}
greet(‘小明’); // ‘小明’是实参
console.log(`你好, ${name}!`);
}
greet(‘小明’); // ‘小明’是实参
2. 默认参数 (ES6+)
当参数未提供时使用默认值:
function sayHello(name = ‘朋友’) {
console.log(`你好, ${name}!`);
}
sayHello(); // 输出: 你好, 朋友!
console.log(`你好, ${name}!`);
}
sayHello(); // 输出: 你好, 朋友!
3. 剩余参数 (ES6+)
收集多个参数为数组:
function sum(…numbers) {
return numbers.reduce((a, b) => a + b, 0);
}
console.log(sum(1, 2, 3)); // 6
return numbers.reduce((a, b) => a + b, 0);
}
console.log(sum(1, 2, 3)); // 6
📌 JavaScript函数不检查实参的数量:
实参少于形参时,缺少的参数值为undefined
实参多于形参时,多余参数会被忽略(但可通过arguments或剩余参数获取)
四、函数的调用
1. 直接调用
function sayHi() {
console.log(‘你好!’);
}
sayHi(); // 直接调用
console.log(‘你好!’);
}
sayHi(); // 直接调用
2. 作为方法调用
作为对象的方法调用:
const person = {
name: ‘小明’,
sayName: function() {
console.log(this.name);
}
};
person.sayName(); // 作为方法调用
name: ‘小明’,
sayName: function() {
console.log(this.name);
}
};
person.sayName(); // 作为方法调用
3. 使用call/apply调用
显式设置this值:
function introduce(greeting) {
console.log(`${greeting}, 我是${this.name}`);
}
const person = { name: ‘小红’ };
// 使用call (参数逐个传递)
introduce.call(person, ‘你好’);
// 使用apply (参数以数组传递)
introduce.apply(person, [‘你好’]);
console.log(`${greeting}, 我是${this.name}`);
}
const person = { name: ‘小红’ };
// 使用call (参数逐个传递)
introduce.call(person, ‘你好’);
// 使用apply (参数以数组传递)
introduce.apply(person, [‘你好’]);
4. 使用bind创建新函数
绑定this值和部分参数:
const personIntro = introduce.bind(person, ‘你好’);
personIntro(); // 输出: 你好, 我是小红
personIntro(); // 输出: 你好, 我是小红
💡 箭头函数没有自己的this值,它继承自外层作用域,因此call/apply/bind无法改变箭头函数的this。
五、函数返回值
函数可以通过return语句返回一个值:
function add(a, b) {
return a + b;
}
const result = add(2, 3); // result = 5
return a + b;
}
const result = add(2, 3); // result = 5
重要特性:
- 函数执行到return语句会立即结束
- 没有return语句的函数返回undefined
- return后面没有值也返回undefined
- 函数只能返回一个值(但可以是对象或数组)
📌 返回多个值的小技巧:
function getDimensions() {
return {
width: 10,
height: 20
};
}
function getCoordinates() {
return [30, 50];
}
return {
width: 10,
height: 20
};
}
function getCoordinates() {
return [30, 50];
}
六、特殊函数特性
1. 函数提升
函数声明会被提升到作用域顶部:
// 可以在声明前调用
sayHello(); // 输出: 你好!
function sayHello() {
console.log(‘你好!’);
}
sayHello(); // 输出: 你好!
function sayHello() {
console.log(‘你好!’);
}
2. 立即执行函数(IIFE)
定义后立即执行的函数:
(function() {
console.log(‘这个函数立即执行!’);
})();
// 带参数的IIFE
(function(name) {
console.log(‘你好, ‘ + name);
})(‘小明’);
console.log(‘这个函数立即执行!’);
})();
// 带参数的IIFE
(function(name) {
console.log(‘你好, ‘ + name);
})(‘小明’);
3. 闭包
函数可以记住并访问它被创建时的作用域:
function createCounter() {
let count = 0;
return function() {
count++;
return count;
};
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
let count = 0;
return function() {
count++;
return count;
};
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
💡 闭包是JavaScript中强大的特性,常用于创建私有变量和模块模式。
七、不同函数定义方式对比
特性 | 函数声明 | 函数表达式 | 箭头函数 | Function构造函数 |
---|---|---|---|---|
提升特性 | ✅ 是 | ❌ 否 | ❌ 否 | ❌ 否 |
this绑定 | 动态 | 动态 | 词法(无自己的this) | 动态 |
arguments对象 | ✅ 有 | ✅ 有 | ❌ 无 | ✅ 有 |
构造函数能力 | ✅ 可以 | ✅ 可以 | ❌ 不可以 | ✅ 可以 |
prototype属性 | ✅ 有 | ✅ 有 | ❌ 无 | ✅ 有 |
语法简洁性 | 中等 | 中等 | ✅ 高 | ❌ 低 |
适用场景 | 通用函数 | 回调函数、条件定义 | 回调、短函数 | 动态创建函数 |