You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何以编程方式实现TypeScript函数链式调用?

Understanding Programmatic Chaining with Your MyChain Class

Great question—let’s break down exactly why this works under the hood in JavaScript, using your code as a guide.

1. The Core of Chaining: Methods Return this

First, look at every method in your MyChain class:

sum(args: number[]) {
  this.value = args.reduce((s, c) => s + c, 0);
  return this; // <-- This is the magic!
}
add(v: number) {
  this.value = this.value + v;
  return this;
}
subtract(v: number) {
  this.value = this.value - v;
  return this;
}

When you call any of these methods on a MyChain instance (like mc.sum([1,2,3])), two critical things happen:

  • The method updates the instance’s value property directly (it modifies the object’s state in place).
  • It returns a reference to the exact same instance via this.

This is why manual chaining (mc.sum(...).subtract(...)) works: each method hands you back the same object, so you can immediately call another method on it.

2. What’s Actually Happening in Your forEach Loop

Let’s assume you started with an instance like this:

const mc = new MyChain();

Then you loop through your chainObj array:

chainObj.forEach(o => {
  mc = mc[o.action](o.operand);
});

You might wonder why this doesn’t "overwrite" the instance each time—here’s the breakdown:

  • mc[o.action](o.operand) calls the method (e.g., sum or subtract) on the current mc instance.
  • That method modifies the instance’s value and returns the same instance (not a new object).
  • Assigning mc = ... just reassigns the variable to point to the same object it already referenced. In fact, you could even omit the assignment entirely (mc[o.action](o.operand);) and get the exact same result—since the method is modifying the instance’s state directly.

3. JavaScript Object References: The Big Picture

JavaScript uses reference semantics for objects (including class instances). When you create const mc = new MyChain(), mc doesn’t store the object itself—it stores a reference to the object in memory.

When your method returns this, it’s returning that same reference. So every time you call a method on mc, you’re operating on the exact same underlying object. The loop is just automating the sequence of method calls, rather than writing them out manually like mc.sum(...).subtract(...).

4. Why Square Bracket Syntax Works

Your use of mc[o.action] is just dynamic method access—instead of hardcoding the method name (like mc.sum), you’re using the string from your action property to look up the method on the instance. This behaves exactly the same as calling the method directly; the only difference is how you reference the method name.

Step-by-Step Walkthrough of Your Example

Let’s trace through your chainObj array to see it in action:

  1. First iteration: action: "sum", operand: [1,2,3,4,5]
    • mc["sum"]([1,2,3,4,5]) calls the sum method on the mc instance.
    • The method calculates the total (15) and sets mc.value = 15.
    • It returns the same mc instance.
    • mc = mc does nothing (same reference), but the instance’s state is now updated.
  2. Second iteration: action: "subtract", operand: 5
    • mc["subtract"](5) calls the subtract method on the same instance.
    • It sets mc.value = 15 - 5 = 10.
    • Returns the same instance again.

At the end, mc.value is 10—exactly what you’d get from manual chaining: mc.sum([1,2,3,4,5]).subtract(5).value.

Quick Refactor Tip

Since the assignment mc = ... is redundant (you’re just reassigning to the same reference), you can simplify the loop to:

chainObj.forEach(o => mc[o.action](o.operand));

This will produce the exact same result, as you’re directly modifying the instance’s state with each method call.

内容的提问来源于stack exchange,提问作者Dan7el

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 19:52:44