console.log(sum(1)(2)(3));  // -> 6
console.log(sum(3)(15));   // -> 18 

function sum(a) {
  let currentSum = a;

  function f(b) {
    currentSum += b;
    return f;
  }
  f.toString = function() {
    return currentSum;
  };
  return f;
}

此函数将传递给它的参数相加,并在所有相加之后返回字符串CurrentSum.我真的不理解到原语的转换是如何发生的,以及为什么要通过函数编写它

推荐答案

函数的默认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;
}

Javascript相关问答推荐

橡皮擦完全让画布变成白色

JavaScript文本区域阻止KeyDown/KeyUp事件本身上的Alt GR +键组合

使用JavaScript在ionic Web应用程序中更新.pane和.view的背景 colored颜色

从实时数据库(Firebase)上的子类别读取数据

如何在JavaScript文件中使用Json文件

如何控制Reaction路由加载器中的错误状态?

如何强制Sphinx中的自定义js/css文件始终加载更改而不缓存?

在Matter.js中添加从点A到另一个约束的约束

如何在Svelte中从一个codec函数中调用error()?

覆盖加载器页面避免对页面上的元素进行操作

Phaserjs-创建带有层纹理的精灵层以自定义外观

按什么顺序接收`storage`事件?

使用jQuery find()获取元素的属性

Node.js错误: node 不可单击或不是元素

是否可以在不更改组件标识的情况下换出Reaction组件定义(以维护状态/引用等)?如果是这样的话,是如何做到的呢?

JAVASCRIPT SWITCH CASE语句:当表达式为';ALL';

不协调嵌入图片

谷歌饼图3D切片

将字体样式应用于material -UI条形图图例

单击子按钮时将活动切换类添加到父分区