JavaScript函数

函数是一段可重复使用的代码块,用于执行特定任务。在JavaScript中,函数是一等公民,可以作为参数传递、作为返回值、赋值给变量等。

函数定义

JavaScript有多种函数定义方式。

函数声明

使用function关键字声明函数:

javascript
function greet(name) {
    return "Hello, " + name + "!";
}

函数表达式

将函数赋值给变量:

javascript
const greet = function(name) {
    return "Hello, " + name + "!";
};

箭头函数

ES6引入的箭头函数语法:

javascript
const greet = (name) => {
    return "Hello, " + name + "!";
};

// 简化形式
const greet = name => "Hello, " + name + "!";

函数构造函数

使用Function构造函数创建函数(不推荐,仅作了解):

javascript
const greet = new Function("name", "return 'Hello, ' + name + '!';");

生成器函数

ES6引入的生成器函数,用于生成迭代器:

javascript
function* countGenerator() {
    let count = 0;
    while (true) {
        yield count++;
    }
}

const counter = countGenerator();
console.log(counter.next().value); // 0
console.log(counter.next().value); // 1

函数参数

函数参数是传递给函数的值。

基本参数

javascript
function add(a, b) {
    return a + b;
}

console.log(add(5, 3)); // 8

默认参数

ES6引入的默认参数:

javascript
function greet(name = "World") {
    return "Hello, " + name + "!";
}

console.log(greet()); // Hello, World!
console.log(greet("John")); // Hello, John!

剩余参数

使用...语法接收剩余参数:

javascript
function sum(...numbers) {
    return numbers.reduce((total, num) => total + num, 0);
}

console.log(sum(1, 2, 3, 4, 5)); // 15

展开运算符

使用...语法传递数组或对象作为参数:

javascript
function add(a, b, c) {
    return a + b + c;
}

const numbers = [1, 2, 3];
console.log(add(...numbers)); // 6

解构参数

使用解构语法接收参数:

javascript
function printPerson({ name, age }) {
    console.log(`Name: ${name}, Age: ${age}`);
}

const person = { name: "John", age: 30 };
printPerson(person); // Name: John, Age: 30

返回值

使用return语句从函数返回值。

基本返回值

javascript
function multiply(a, b) {
    return a * b;
}

const result = multiply(5, 3);
console.log(result); // 15

无返回值

如果函数没有明确的return语句,将返回undefined

javascript
function greet(name) {
    console.log("Hello, " + name + "!");
}

const result = greet("John");
console.log(result); // undefined

早期返回

可以在函数的任何位置使用return语句提前返回:

javascript
function isPositive(number) {
    if (number > 0) {
        return true;
    }
    return false;
}

返回对象

javascript
function createPerson(name, age) {
    return {
        name: name,
        age: age
    };
}

const person = createPerson("John", 30);

返回函数

函数可以返回另一个函数:

javascript
function createMultiplier(factor) {
    return function(number) {
        return number * factor;
    };
}

const double = createMultiplier(2);
console.log(double(5)); // 10

作用域

作用域是指变量的可访问范围。

全局作用域

在函数外部声明的变量具有全局作用域:

javascript
let globalVar = "I'm global";

function showGlobalVar() {
    console.log(globalVar); // 可以访问全局变量
}

showGlobalVar(); // I'm global

函数作用域

在函数内部声明的变量具有函数作用域,只能在函数内部访问:

javascript
function showLocalVar() {
    let localVar = "I'm local";
    console.log(localVar); // 可以访问局部变量
}

showLocalVar(); // I'm local
console.log(localVar); // 报错:localVar is not defined

块级作用域

ES6引入的letconst声明的变量具有块级作用域({}内):

javascript
if (true) {
    let blockVar = "I'm in block";
    console.log(blockVar); // I'm in block
}

console.log(blockVar); // 报错:blockVar is not defined

作用域链

当在函数内部访问变量时,JavaScript会先在当前函数作用域查找,如果找不到,会向上查找父函数作用域,直到全局作用域:

javascript
let globalVar = "global";

function outer() {
    let outerVar = "outer";
    
    function inner() {
        let innerVar = "inner";
        console.log(innerVar); // inner
        console.log(outerVar); // outer
        console.log(globalVar); // global
    }
    
    inner();
}

outer();

闭包

闭包是指有权访问另一个函数作用域中变量的函数:

javascript
function createCounter() {
    let count = 0;
    
    return function() {
        return ++count;
    };
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

闭包的特点:

  • 可以访问外部函数的变量
  • 外部函数执行完毕后,其变量仍然可以被闭包访问
  • 可以创建私有变量

函数调用

普通调用

javascript
function greet(name) {
    return "Hello, " + name + "!";
}

greet("John"); // 普通调用

作为方法调用

javascript
const person = {
    name: "John",
    greet: function() {
        return "Hello, " + this.name + "!";
    }
};

person.greet(); // 作为方法调用,this指向person对象

使用call()调用

javascript
function greet(greeting) {
    return greeting + ", " + this.name + "!";
}

const person = { name: "John" };
console.log(greet.call(person, "Hi")); // Hi, John!

使用apply()调用

javascript
function greet(greeting, punctuation) {
    return greeting + ", " + this.name + punctuation;
}

const person = { name: "John" };
console.log(greet.apply(person, ["Hi", "!"])); // Hi, John!

使用bind()创建新函数

javascript
function greet(greeting) {
    return greeting + ", " + this.name + "!";
}

const person = { name: "John" };
const greetPerson = greet.bind(person);
console.log(greetPerson("Hi")); // Hi, John!

函数属性

函数具有以下内置属性:

name

获取函数名称:

javascript
function greet() {}
console.log(greet.name); // greet

const anonymous = function() {};
console.log(anonymous.name); // anonymous

const arrow = () => {};
console.log(arrow.name); // arrow

length

获取函数参数个数:

javascript
function add(a, b, c) {
    return a + b + c;
}

console.log(add.length); // 3

arguments

函数内部的arguments对象包含了所有传入的参数:

javascript
function sum() {
    let total = 0;
    for (let i = 0; i < arguments.length; i++) {
        total += arguments[i];
    }
    return total;
}

console.log(sum(1, 2, 3, 4, 5)); // 15

递归

递归是指函数调用自身:

javascript
function factorial(n) {
    if (n <= 1) {
        return 1;
    }
    return n * factorial(n - 1);
}

console.log(factorial(5)); // 120

递归的特点:

  • 必须有终止条件
  • 可能会导致栈溢出
  • 可以简化某些算法的实现

函数式编程

JavaScript支持函数式编程范式,主要特点包括:

纯函数

纯函数是指相同的输入总是产生相同的输出,并且没有副作用的函数:

javascript
// 纯函数
function add(a, b) {
    return a + b;
}

// 非纯函数(修改外部变量)
let count = 0;
function increment() {
    return ++count;
}

高阶函数

高阶函数是指接受函数作为参数或返回函数的函数:

javascript
// 接受函数作为参数
function map(arr, transform) {
    const result = [];
    for (let item of arr) {
        result.push(transform(item));
    }
    return result;
}

// 返回函数
function createAdder(a) {
    return function(b) {
        return a + b;
    };
}

继续学习:JavaScript对象

最后更新:2026-02-08