ES6 - 函数
ES6 - 函数
Section titled “ES6 - 函数”函数是 JavaScript 中的基本构建块,允许您封装一段可多次执行的代码。ES6 (ECMAScript 2015) 及后续版本为函数语法和功能引入了多项强大的增强。
1. 函数声明:
Section titled “1. 函数声明:”会被提升 (Hoisted) 到其作用域的顶部,这意味着可以在代码中定义之前调用它们。
function greet(name) { console.log(`Hello, ${name}!`);}greet("World"); // Output: Hello, World!2. 函数表达式:
Section titled “2. 函数表达式:”赋值给一个变量。不会被提升;只能在赋值之后调用。
const add = function(a, b) { return a + b;};console.log(add(5, 3)); // Output: 8箭头函数 (Arrow Functions) (ES6)
Section titled “箭头函数 (Arrow Functions) (ES6)”箭头函数提供了一种更简洁的语法来编写函数表达式,并在处理 this 方面有一个重要的区别:它们词法绑定了 this,这意味着箭头函数内部的 this 指向其外部(封闭)词法作用域的 this 值。它们不适用于所有情况(例如,需要自己 this 上下文的方法,或作为构造函数)。
- 基本形式:
(param1, param2) => { statements } - 单个参数(括号可选):
param => { statements } - 无参数:
() => { statements } - 单个表达式(隐式返回,省略花括号和
return关键字):(param1, param2) => expression
箭头函数示例:
Section titled “箭头函数示例:”const multiply = (x, y) => x * y;console.log(multiply(4, 5)); // 输出: 20
const square = num => num * num; // 单个参数时括号可选console.log(square(7)); // 输出: 49
const sayHi = () => console.log("Hi there!");sayHi(); // 输出: Hi there!
const numbers = [1, 2, 3, 4];const doubled = numbers.map(n => n * 2);console.log(doubled); // 输出: [2, 4, 6, 8]箭头函数中的词法 this:
Section titled “箭头函数中的词法 this:”function Timer() { this.seconds = 0; // 在传统函数中,setInterval 内部的 'this' 将是全局对象或 undefined (严格模式下) // setInterval(function() { // // 这里的 'this' 不是 Timer 实例 // this.seconds++; // console.log(this.seconds); // }, 1000);
// 箭头函数从 Timer 构造函数作用域继承 'this' setInterval(() => { this.seconds++; console.log(`Timer (lexical this): ${this.seconds}`); }, 1000);}// 在浏览器/Node 环境中取消注释运行此示例// const myTimer = new Timer();默认参数值 (Default Parameter Values) (ES6):
Section titled “默认参数值 (Default Parameter Values) (ES6):”您可以为函数参数指定默认值。如果未提供该参数的实参或实参为 undefined,则使用默认值。
默认参数示例:
Section titled “默认参数示例:”function greetUser(name = "Guest", message = "Welcome") { console.log(`${message}, ${name}!`);}greetUser(); // 输出: Welcome, Guest!greetUser("Alice"); // 输出: Welcome, Alice!greetUser("Bob", "Good morning"); // 输出: Good morning, Bob!剩余参数 (Rest Parameters) (ES6):
Section titled “剩余参数 (Rest Parameters) (ES6):”剩余参数语法 (...paramName) 允许函数接受不确定数量的参数并将其作为一个数组。它必须是函数定义中的最后一个参数。
剩余参数示例:
Section titled “剩余参数示例:”function sumAll(...numbers) { let total = 0; for (const num of numbers) { total += num; } return total;}console.log(sumAll(1, 2, 3)); // 输出: 6console.log(sumAll(10, 20, 30, 40, 50)); // 输出: 150console.log(sumAll()); // 输出: 0函数调用中的展开语法 (Spread Syntax) (...) (ES6):
Section titled “函数调用中的展开语法 (Spread Syntax) (...) (ES6):”展开语法允许将可迭代对象(如数组)在函数调用中展开为单个参数。
展开语法示例:
Section titled “展开语法示例:”function calculateProduct(a, b, c) { return a * b * c;}const values = [2, 3, 4];console.log(calculateProduct(...values)); // 相当于 calculateProduct(2, 3, 4) -> 输出: 24Function 构造函数(不常用):
Section titled “Function 构造函数(不常用):”函数也可以使用 Function 构造函数动态创建:new Function(arg1, arg2, ..., functionBody)。但是,由于安全风险(类似于 eval())和性能影响(函数体在运行时解析),通常不建议使用此方法。
调用自身的函数称为递归函数。递归对于解决可以分解为更小、自相似子问题的问题很有用。需要一个基本情况来停止递归。
使用递归计算阶乘示例:
Section titled “使用递归计算阶乘示例:”function factorial(n) { if (n < 0) return undefined; // 阶乘对于负数未定义 if (n === 0 || n === 1) { return 1; // 基本情况 } else { return n * factorial(n - 1); // 递归步骤 }}console.log(factorial(5)); // 输出: 120立即调用函数表达式 (IIFE)
Section titled “立即调用函数表达式 (IIFE)”IIFE 是一个被定义后立即执行的函数。在历史上,IIFE 常用于为变量创建私有作用域,以避免污染全局作用域(使用 var 时)。随着 ES6 let 和 const 提供了块级作用域,以及模块提供了真正的封装,IIFE 在作用域管理方面的需求有所减少,但它们仍然可以用于初始化或创建闭包。
IIFE 示例:
Section titled “IIFE 示例:”(function() { const message = "This is from an IIFE!"; console.log(message);})();// 在这里无法访问 message生成器函数 (Generator Functions) (ES6):
Section titled “生成器函数 (Generator Functions) (ES6):”生成器函数(function* name() { ... })是一种特殊的函数,可以暂停和恢复执行,从而允许它们随时间产生一系列值。它们使用 yield 关键字来暂停并返回一个值。调用生成器函数时,它会返回一个迭代器 (iterator) 对象。
生成器函数示例:
Section titled “生成器函数示例:”function* countUpTo(max) { let count = 1; while (count <= max) { yield count++; // 暂停并生成 (yield) 当前计数 }}
const counter = countUpTo(3);console.log(counter.next()); // { value: 1, done: false }console.log(counter.next()); // { value: 2, done: false }console.log(counter.next()); // { value: 3, done: false }console.log(counter.next()); // { value: undefined, done: true }
// 也可以与 for...of 循环一起使用for (const num of countUpTo(3)) { console.log(`For...of: ${num}`);}生成器是高级异步模式的基础,例如 async/await 中使用的模式(尽管 async/await 本身是 Promise 之上的更高层抽象)。