函数的默认toString
函数将返回字符串化的函数.要显示f
的(中间的、封闭的)currentSum
值,您需要覆盖那个toString
函数.也许这段代码可以澄清这一点:
function sum(a) {
let currentSum = a;
function f(value = 0) {
currentSum += value;
return f;
}
f.toString = function() {
return currentSum;
};
return f;
}
function someFunction() {
return 1;
}
// a functions default 'toString'
console.log(`${someFunction}`);
const six = sum(1)(2)(3);
// six is a function
console.log(`const six = sum(1)(2)(3);
typeof six: ${typeof six}`);
// toString (of the function) is automatically
// invoked within a template string
console.log(`current value of six: ${six}`);
// change [currentSum] (six is still a function)
console.log(`typeof six(10): ${typeof six(10)}`);
// the value of six has changed
console.log(`current value of six: ${six}`);
.as-console-wrapper {
max-height: 100% !important;
}
有趣的是:因为Function
等于just another Object
,所以您也可以用自己的"Value"方法来扩展它.在这种情况下,您必须显式调用扩展方法(S)来检索包含的值.
function sum(a = 0) {
let currentSum = a;
const f = (value = 0) => {
currentSum += value;
return f;
}
// extend
f.value = _ => currentSum;
f.reset = _ => { currentSum = 0; return f; }
f.increment = _ => { currentSum += 1; return f; }
return f;
}
const six = sum()(1)(2)(3);
console.log(`six.value(): ${six.value()}`);
console.log(`six(10).value(): ${six(10).value()}`);
console.log(`six.increment().value(): ${six.increment().value()}`);
console.log(`six.reset().value(): ${six.reset().value()}`);
console.log(`six(1)(2)(3).value(): ${six.reset()(1)(2)(3).value()}`);
.as-console-wrapper {
max-height: 100% !important;
}
进一步的步骤可能是将方法转换为getter(这样您就不需要使用它们的括号),或者将您自己的setter添加到函数中:
function sum(a = 0) {
let currentSum = a;
function f(value = 0){
currentSum += value;
return f;
}
const extensions = {
get value() { return currentSum; },
set value(val) {currentSum = val; return f; },
get reset() { currentSum = 0; return f; },
get increment() { currentSum += 1; return f; },
};
Object.entries(Object.getOwnPropertyDescriptors(extensions))
.forEach( ([key, descriptor]) => {
Object.defineProperty(f, key, descriptor);
} );
return f;
}
const six = sum(1)(2)(3);
console.log(`native six.toString(): ${six}`);
console.log(`six.value: ${six.value}`);
console.log(`six(10).value: ${six(10).value}`);
console.log(`six.increment.value: ${six.increment.value}`);
console.log(`six.reset.value: ${six.reset.value}`);
console.log(`six.increment(2)(3).value: ${six.increment(2)(3).value}`);
six.value = 12;
console.log(`six.value = 12;
six(30).value: ${six(30).value}`);
.as-console-wrapper {
max-height: 100% !important;
}