通过 Class 实现链式调用
问题
const result = new Chainable()
.add(5)
.subtract(2)
.multiply(3)
.divide(2)
.getValue();
题解
class Chainable {
constructor(value = 0) {
this.value = value;
}
add(num) {
this.value += num;
return this;
}
subtract(num) {
this.value -= num;
return this;
}
multiply(num) {
this.value *= num;
return this;
}
divide(num) {
if (num !== 0) {
this.value /= num;
} else {
console.error("Cannot divide by zero");
}
return this;
}
getValue() {
return this.value;
}
}
// 使用示例
const result = new Chainable()
.add(5)
.subtract(2)
.multiply(3)
.divide(2)
.getValue();
console.log(result); // 输出结果
通过闭包实现链式调用
问题
实现一个 add 函数,该函数可以链式调用
add(1)(2)(3)
得到 6。但是如何得到这个值?
目前想到的有以下方法:
1:通过 .value 来获取值
function add(currentValue) {
function sum(addValue) {
return add(currentValue + addValue)
};
sum.value = currentValue;
return sum;
}
// 使用示例
console.log(add(1)(2)(3).value); // 输出 6
首次调用 add(1) 返回值为 1 的 sum 函数。
接下来每次调用 sum 函数:对值为 1 的 sum 函数调用 sum(2),会返回 add(3),add(3) 会返回值为 3 的 sum 函数……
function add(a) {
let sum = a;
function adder(b) {
sum += b;
adder.value = sum;
return adder;
}
adder.value = sum;
return adder;
}
console.log(add(1)(2)(3).value); // 输出 6
console.log(add(1)(2)(3)(4).value); // 输出 10
console.log(add(5).value); // 输出 5
首次调用 add 会创建一个 adder 函数,该函数可以访问到外层的 sum。
每次调用 adder 函数会增加外层的 sum,并更新 adder 函数的 value。
每次调用 adder 函数会返回 adder 函数自身。
2:通过不传递参数来获取值
function add(a) {
let sum = a;
function adder(b) {
if (b === undefined) {
return sum;
}
sum += b;
return adder;
}
return adder;
}
console.log(add(1)(2)(3)()); // 输出 6
console.log(add(1)(2)(3)(4)()); // 输出 10
console.log(add(5)()); // 输出 5
3:通过指定调用次数来在最后获取值
function createAdder(n) {
return function adder(a, level = n) {
if (level === 1) {
return a;
}
return function sum(b) {
return adder(a + b, level - 1);
};
};
}
const add3 = createAdder(3);
console.log(add3(1)(2)(3)); // 输出 6
const add4 = createAdder(4);
console.log(add4(1)(2)(3)(4)); // 输出 10
调用 createAdder(3) 会返回剩余使用次数为 3 的 adder 函数。
首次调用 adder 函数:如果 adder 函数只剩一层,返回数字,否则返回 sum 函数。之后每次调用的都是 sum 函数。
调用 sum 函数会加上累加数,减少层级调用 adder 函数:如果 adder 函数只剩一层,返回数字,否则返回 sum 函数。