0Pricing
JavaScript Academy · 课时

工厂函数

通过闭包创建带有私有状态的对象。

工厂函数 是 CoddyKit 上的免费 JavaScript Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 JavaScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 JavaScript Academy 课程共包含 4 节课。

什么是工厂函数

工厂函数是任何返回新对象的函数。与构造函数不同,您可以像普通函数一样调用它(不使用 new),并且它可以使用闭包保存私有状态。

function createUser(name) {
  return {
    name,
    greet: () => "Hi, I am " + name
  };
}
const u = createUser("Ada");
console.log(u.greet()); // "Hi, I am Ada"

不使用 new 关键字

工厂函数可以避免 new 和 this 带来的问题。您只需调用函数,就能得到一个对象。

function point(x, y) {
  return { x, y };
}
const p = point(3, 4);
console.log(p.x, p.y); // 3 4

通过闭包实现私有状态

在工厂函数中声明的变量是私有的。返回的对象方法会围绕这些变量形成闭包,就像模块模式一样,只不过可以生成多个实例。

function createCounter() {
  let count = 0; // private
  return {
    inc: () => ++count,
    get: () => count
  };
}
const c = createCounter();
c.inc();
console.log(c.get()); // 1

多个相互独立的实例

工厂的每次调用都会生成一个拥有独立私有状态的新对象。这是它与单例模块的关键区别。

function createCounter() {
  let n = 0;
  return { inc: () => ++n };
}
const a = createCounter();
const b = createCounter();
console.log(a.inc(), a.inc()); // 1 2
console.log(b.inc());          // 1

计算属性

工厂函数可以在创建时派生值,并公开计算方法,同时保持输入私有。

function rectangle(w, h) {
  return {
    area: () => w * h,
    perimeter: () => 2 * (w + h)
  };
}
const r = rectangle(3, 4);
console.log(r.area());      // 12
console.log(r.perimeter()); // 14

默认配置与可选配置

由于工厂函数就是普通函数,因此可以通过解构清晰地处理默认值和选项。

function createButton({ label = "OK", disabled = false } = {}) {
  return { label, disabled };
}
console.log(createButton());             // { label: "OK", disabled: false }
console.log(createButton({ label: "Go" })); // { label: "Go", disabled: false }

组合优于继承

工厂函数倾向于使用组合:通过混入行为来构建对象,而不是扩展一条类继承链。

const canFly = (s) => ({ fly: () => s.name + " flies" });
function createBird(name) {
  const self = { name };
  return Object.assign(self, canFly(self));
}
console.log(createBird("Robin").fly()); // "Robin flies"

共享行为

如果要让多个实例共享方法而不为每个实例创建副本,可以先定义一次再进行分配。您也可以为了闭包带来的隐私优势,接受少量的成本。

const behavior = {
  describe() { return "id " + this.id; }
};
function createItem(id) {
  return Object.assign({ id }, behavior);
}
console.log(createItem(7).describe()); // "id 7"

也可以返回函数

当返回函数能提供更简洁的接口时,工厂函数也可以返回函数而不是对象,同时仍然捕获私有状态。

function multiplier(factor) {
  return (n) => n * factor;
}
const triple = multiplier(3);
console.log(triple(5)); // 15

工厂函数与构造函数

构造函数使用 new、this 和原型链。工厂函数更加简单,可以避免 this 引发的错误,并通过闭包提供真正的隐私;代价是无法在原型上共享方法。

创建时进行验证

工厂函数可以验证输入,并在返回对象之前抛出错误或进行规范化,从而保证生成的每个对象都有效。

function createAge(value) {
  if (value < 0) throw new Error("age must be >= 0");
  return { value };
}
console.log(createAge(30).value); // 30

快速检查

工厂函数。

回顾

工厂函数无需使用 new 或 this 即可返回对象,并使用闭包保存私有状态。每次调用都会产生独立的实例,同时支持计算属性、默认配置、组合和验证。它牺牲了原型方法共享,换来了简单性和真正的隐私,因而成为构造函数的一种简洁、由闭包驱动的替代方案。

常见问题解答

「工厂函数」课时是免费的吗?

是的 — 「工厂函数」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 JavaScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 JavaScript Academy 课程共包含 4 节课。

「工厂函数」这节课中我会学到什么?

通过闭包创建带有私有状态的对象。 你通过在浏览器中直接运行的动手代码来练习 JavaScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 JavaScript Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 JavaScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「工厂函数」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 JavaScript Academy 课中编写并运行代码吗?

能。每节 JavaScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 闭包如何捕获状态
  2. 使用闭包创建私有变量
  3. 模块模式(IIFE)
  4. 工厂函数
← 返回 JavaScript Academy