No.1
第一次考的题是这样的,要求如下:
// 写一个sum函数
// sum(1, 2) ---> 3
// sum(3)
// sum(4) // ---> 7
// sum(2,3,4) // ---> 9
我原本的思路是想用闭包来实现的,先拆分成两个函数去写。
首先看到这个输出,把题意的需求拆解为两个关键点:
- 如果只传入一个参数,才需要累加之前的结果。
- 如果传入的是多个参数,就只累加参数,而不计之前的结果。
let lastSum = 0;
function sum(...args) {
if (args.length === 1) {
lastSum += args[0];
return lastSum;
} else {
const result = args.reduce((acc, val) => acc + val, 0);
lastSum = result; // 更新 lastSum 以便下次使用
return result;
}
}
console.log(sum(1, 2)); // 输出 3
console.log(sum(3)); // 输出 6 (因为之前已经加了 3)
console.log(sum(4)); // 输出 10 (因为之前已经加了 7)
console.log(sum(2, 3, 4)); // 输出 9 (只累加这些参数)
这是定义了一个全局变量的写法,并没能很好地封装sum函数。用闭包能够解决这个问题。
function createSum() {
let lastSum = 0;
function sum(...args) {
if (args.length === 1) {
lastSum += args[0];
return lastSum;
} else {
const result = args.reduce((acc, val) => acc + val, 0);
return result;
}
}
return sum;
}
const sum = createSum();
console.log(sum(1, 2)); // 输出 3
console.log(sum(3)); // 3 (没有做任何累加,输出原参)
console.log(sum(4)); // 输出 7
console.log(sum(2, 3, 4)); // 输出 9 (只累加这些参数)
可能会有小白看不懂这一步const sum = createSum();执行了之后为什么闭包还存在。
但是事实情况是,正是因为这一步,闭包才存在。
const sum = createSum();可以拆,首先是createSum(),这意味着调用了creatSum函数,然后再把调用过creatSum函数的返回值,赋值给sum。
这样,sum 变量就存储了 creatSum 函数执行后的结果。
No.2
第二个题目是,也是sum但是变了一种形式。
// sum(1, 2, 3).sumOf(); //6
// sum(2, 3)(2).sumOf(); //7
// sum(1)(2)(3)(4).sumOf(); //10
// sum(2)(4, 1)(2).sumOf(); //9
实现思路如下:
function createSum() {
let total = 0;
let argsSoFar = [];
function sum(...args) {
if (args.length > 0) {
argsSoFar.push(...args);
}
return {
sumOf: function() {
total += argsSoFar.reduce((acc, val) => acc + val, 0);
argsSoFar = []; // 重置已累积的参数
return total;
}
};
}
return sum;
}
const sum = createSum();
console.log(sum(1, 2, 3).sumOf()); // 输出 6
console.log(sum(2, 3)(2).sumOf()); // 输出 7
console.log(sum(1)(2)(3)(4).sumOf()); // 输出 10
console.log(sum(2)(4, 1)(2).sumOf()); // 输出 9