Skip to content

Commit 974b855

Browse files
authored
feat: JS 中的链式调用 (#174)
* feat: 新增关于 JavaScript 中链式调用的文章,涵盖数组、对象方法、Promise 及管道操作符的实现示例 * feat: 添加多变量和多函数嵌套链式调用示例,更新 Promise 链式调用实现,提升代码可读性 * rf: 变更文件名 * chore: update last modified date for the method chaining in JavaScript article * feat: 添加匿名函数示例以展示 JavaScript 中的链式调用,提升代码示例的灵活性和可读性
1 parent 14ec81c commit 974b855

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
---
2+
title: JS 中的链式调用
3+
categories: [javascript, ecmascript]
4+
author: iugo
5+
date: 2025-01-14
6+
last_modified_at: 2025-01-15 15:48+08:00
7+
---
8+
9+
## 数组中的链式调用
10+
11+
```ts
12+
const numbers = [1, 2, 3, 4, 5];
13+
const result = numbers
14+
.filter(n => n % 2 === 0) // 过滤偶数
15+
.map(n => n * 2) // 每个数乘以2
16+
.reduce((sum, n) => sum + n, 0); // 求和
17+
```
18+
19+
但是仅限于数组, 如果想要在其他对象上实现链式调用, 就需要自定义方法.
20+
21+
## 多变量链式调用
22+
23+
为了可以对任何数据使用自定义方法, 我们可以这样做:
24+
25+
```ts
26+
function add(x, y) {
27+
return x + y;
28+
}
29+
30+
function multiply(x, y) {
31+
return x * y;
32+
}
33+
34+
let num = 0;
35+
let num2 = add(num, 5);
36+
let num3 = multiply(num2, 2);
37+
let num4 = add(num3, 3);
38+
console.log(num4); // 13
39+
```
40+
41+
这种做法的缺点是额外增加了许多变量, 为了这些变量要进行许多不必要的命名.
42+
43+
## 多函数嵌套链式调用
44+
45+
为了避免不必要的命名, 我们可以直接调用:
46+
47+
```ts
48+
const result = add(multiply(add(0, 5), 2), 3);
49+
console.log(result); // 13
50+
```
51+
52+
可是这样做后, 代码的可读性很差.
53+
54+
## 对象方法链式调用
55+
56+
```ts
57+
class Calculator {
58+
constructor() {
59+
this.value = 0;
60+
}
61+
add(n) {
62+
this.value += n;
63+
return this;
64+
}
65+
66+
multiply(n) {
67+
this.value *= n;
68+
return this;
69+
}
70+
71+
getValue() {
72+
return this.value;
73+
}
74+
}
75+
76+
const calc = new Calculator();
77+
const result = calc
78+
.add(5)
79+
.multiply(2)
80+
.add(3)
81+
.getValue(); // 13
82+
```
83+
84+
但是需要额外新增对象, 并且许多时候函数作为方法并不合适.
85+
86+
## Promise 中的链式调用
87+
88+
为了解决上述问题, 我们可以使用 Promise 的链式调用:
89+
90+
```ts
91+
const result = await Promise.resolve(0)
92+
.then(x => add(x, 5))
93+
.then(x => multiply(x, 2))
94+
.then(x => add(x, 3));
95+
console.log(result); // 13
96+
```
97+
98+
并且这种做法可以仅仅使用匿名函数, 不使用函数, 在一些小变动的时候很方便:
99+
100+
```ts
101+
const result = await Promise.resolve(0)
102+
.then(x => x + 5)
103+
.then(x => x * 2)
104+
.then(x => x + 3);
105+
console.log(result); // 13
106+
```
107+
108+
目前这是我最常用的方法. 但是缺点是强制将代码转为了异步.
109+
110+
## JS Pipe Operator (管道操作符) 提案
111+
112+
<https://github.com/tc39/proposal-pipeline-operator>
113+
114+
参考了几种语言的语法:
115+
116+
1. Hack
117+
2. F#
118+
119+
另外, 许多其他语言也有类似语法, 比如 Elixir.

0 commit comments

Comments
 (0)