普通视图

发现新文章,点击刷新页面。
昨天 — 2026年1月25日首页

JavaScript 函数入门:从基础调用到闭包与模块化

2026年1月25日 18:02

在 JavaScript 的世界里,函数不仅是代码的执行单元,更是构建复杂应用的核心积木。正如你的笔记所言:“函数包含一组语句,它们是 JavaScript 的基础模块单元,用于代码复用、信息隐藏和组合调用。” 本文将系统梳理 JavaScript 函数的核心特性——从其对象本质、四种调用模式,到闭包、模块化等高级概念,助你真正掌握这门语言的灵魂。


一、函数即对象:一切皆可赋值

JavaScript 中最颠覆传统编程认知的一点是:函数是头等对象(First-class Object)

function add(a, b) {
    return a + b;
  }
  
  // 函数可以像普通变量一样被赋值、传递、存储
  var myFunc = add;
  console.log(myFunc(2, 3)); // 5
  
  // 甚至可以作为对象属性(方法)
  var calculator = { operate: add };

✅ 函数对象的特殊性:

  • 它拥有普通对象的所有能力(可添加属性、可作为参数传递);
  • 唯一区别:它可以通过 () 被调用(invoked)
  • 其原型链为:add → Function.prototype → Object.prototype

💡 正因函数是对象,我们才能实现回调、高阶函数、闭包等强大模式。


二、函数字面量:声明的四种方式

最常用的是函数字面量(Function Literal)

// 命名函数(推荐,便于调试)
function greet(name) {
    return "Hello, " + name;
  }
  
  // 匿名函数(常用于回调)
  setTimeout(function() {
    console.log("Delayed!");
  }, 1000);

此外还有:

  • 函数表达式const fn = function() {}
  • 箭头函数(ES6+)const fn = () => {}

📌 命名建议:除非作为简短回调,否则优先使用命名函数,提升堆栈可读性。


三、四大调用模式:this 的命运由谁决定?

函数调用时,会自动获得两个“免费”参数:this 和 arguments。而 this 的指向,取决于调用方式

1. 方法调用模式(Method Invocation)

var obj = {
    name: "Alice",
    sayHi: function() {
      console.log(this.name); // "Alice" —— this 指向 obj
    }
  };
  obj.sayHi();

✅ this 绑定到调用对象,这是面向对象编程的基础。

2. 函数调用模式(Function Invocation)

function sayName() {
    console.log(this); // 非严格模式:window;严格模式:undefined
  }
  sayName(); // 直接调用

⚠️ 危险!  在非严格模式下,this 意外指向全局对象,易引发 bug。

3. 构造器调用模式(Constructor Invocation)

function Person(name) {
    this.name = name; // this 指向新创建的实例
  }
  var p = new Person("Bob");

✅ 使用 new 时:

  • 创建新对象;
  • this 绑定到该对象;
  • 若无显式 return 对象,则返回 this

4. Apply/Call 调用模式(Explicit Invocation)

function introduce() {
    console.log("I'm " + this.name);
  }
  
  var user = { name: "Carol" };
  introduce.call(user);   // "I'm Carol"
  introduce.apply(user);  // 同上(参数以数组形式传入)

✅ 显式指定 this,是实现函数借用、绑定上下文的关键。

🌟 现代替代:ES5+ 的 bind() 可创建永久绑定 this 的新函数。


四、参数与返回:灵活但需谨慎

参数:arguments 对象

function sum() {
    let total = 0;
    for (let i = 0; i < arguments.length; i++) {
      total += arguments[i];
    }
    return total;
  }
  sum(1, 2, 3); // 6
  • arguments 是类数组对象,无 map/forEach 等方法;
  • 现代替代:使用 Rest 参数(...args  获取真数组:
function sum(...numbers) {
    return numbers.reduce((a, b) => a + b, 0);
  }

返回值规则

  • 无 return → 返回 undefined
  • 构造函数中若 return 非对象 → 忽略,仍返回 this
  • 若 return 对象 → 返回该对象(覆盖 this)。

五、闭包:函数的“记忆”能力

闭包 = 内部函数 + 外部作用域的引用

function counter() {
    var count = 0;
    return function() {
      count++;
      return count;
    };
  }
  
  var c = counter();
  console.log(c()); // 1
  console.log(c()); // 2 —— count 被“记住”了!

✅ 闭包的价值:

  • 数据私有化count 外部无法直接访问;
  • 状态保持:函数“记住”了创建时的环境;
  • 模块化基础:实现信息隐藏。

六、模块模式:告别全局污染

利用闭包,可构建模块(Module) ——提供接口但隐藏内部状态:

var MyModule = (function() {
    var privateVar = "secret";
  
    function privateMethod() {
      console.log(privateVar);
    }
  
    return {
      publicMethod: function() {
        privateMethod();
      }
    };
  })();
  
  MyModule.publicMethod(); // "secret"
  // MyModule.privateVar → undefined(无法访问)

✅ 优势

  • 避免全局变量冲突;
  • 实现封装与解耦;
  • 是现代 ES6 模块(import/export)的思想前身。

七、高级技巧:记忆化、套用与级联

1. 记忆化(Memoization)

缓存计算结果,避免重复运算:

function fibonacci(n, memo = {}) {
    if (n in memo) return memo[n];
    if (n <= 1) return n;
    memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo);
    return memo[n];
  }

2. 套用(Currying)

将多参数函数转换为一系列单参数函数:

function add(a) {
    return function(b) {
      return a + b;
    };
  }
  var add5 = add(5);
  add5(3); // 8

3. 级联(Chaining)

方法返回对象自身,支持链式调用:

var obj = {
    value: 0,
    add: function(x) {
      this.value += x;
      return this; // 关键:返回 this
    },
    log: function() {
      console.log(this.value);
      return this;
    }
  };
  
  obj.add(2).add(3).log(); // 5

八、异常处理:优雅应对错误

try {
    throw new Error("Something went wrong!");
  } catch (e) {
    console.error(e.message);
  } finally {
    console.log("Cleanup");
  }
  • throw 抛出异常对象(建议用 Error 实例);
  • catch 捕获并处理;
  • finally 无论是否出错都会执行。

结语:函数是 JavaScript 的灵魂

从简单的代码复用,到复杂的闭包、模块、高阶函数,JavaScript 的函数机制赋予了开发者极大的表达力。理解其对象本质、this 绑定规则、作用域链与闭包原理,是写出健壮、可维护代码的前提。

正如 Douglas Crockford 所言: “JavaScript 的精华,就在于它的函数。”  掌握函数,你就掌握了这门语言的钥匙。

昨天以前首页
❌
❌