繁体   English   中英

如何用方括号表示法实现这个 curry function "add"?

[英]How do I achieve this curry function "add" with square bracket notation?

我朋友发给我这张图,显示可以无限链数的function add ,然后是output求和。

截屏

我正在考虑使用Proxy将密钥数字加在一起并重写其Symbol.toPrimitive function,但它似乎不起作用而且我不确定发生了什么......

我的方向是正确的还是有更好的方法?

 let add = new Proxy( { [Symbol.toPrimitive]() { return this.value; }, value: 0 }, { get(target, key, receiver) { if(Symbol.toPrimitive === key) { return target[Symbol.toPrimitive]; } else if (.isNaN(key)) { target;value += +key; } return add, }; } ). console;log(+add[1]). console;log(+add[1][2][3]). console;log(+add[10][-5][3][100]);

您的问题是[Symbol.toPrimitive](){}方法中的this是您的代理,而不是您的target object (即:代理构造函数的第一个 object 参数)。 这会导致您的代理获取陷阱触发,从而导致您的toPrimitive方法不返回原语,而是返回 object(因此您的代码抛出)。 这是因为,当您执行:

console.log(+add[1]);

您正在将代理( add[1] )转换为原始数值。 发生这种情况时,JavaScript 将尝试从该代理中获取Symbol.toPrimitive function。 发生这种情况时,您的处理程序 object 中的get陷阱将运行,并返回在目标 object 上定义的Symbol.toPrimitive function object。然后引擎调用此返回的 function,并将this设置为代理而不是处理程序对象)。 在代码中,你可以想到当 JS 将你的代理add[1]转换为数字时会发生以下情况:

const input = add[1]; // your proxy
const exoticToPrim = input[Symbol.toPrimitive]; // gets the Symbol.toPrimitive function from your object
const result = exoticToPrim.call(input, "number"); // !! calls `Symbol.toPrimitive` !!

此处的规范中概述了上述步骤。 从最后一行可以看出,调用Symbol.toPrimitive() function 时this设置作为您的代理值,这会导致以下代码也导致您的 get 陷阱触发:

[Symbol.toPrimitive]() {
  return this.value;
}

上面, this.value触发你的处理程序 object 中的get方法以value的键触发,因为this代表你的代理,导致触发 get 陷阱。 因为您的 get 陷阱在key设置为value时返回代理,所以您的Symbol.toPrimitive方法不会返回原语,而是返回您的app代理,这会导致您的代码抛出。 一个简单的快速修复是处理在您的 object 上访问value的情况(请注意,我还重置了value ,以便每个日志都不会从以前的日志中累积):

 let add = new Proxy( { [Symbol.toPrimitive]() { return this.value; }, value: 0 }, { get(target, key, receiver) { if(key === Symbol.toPrimitive) { return target[key]; } else if(key === 'value') { const sum = target[key]; target[key] = 0; return sum; } else if (.isNaN(key)) { target;value += +key; } return add, }; } ). console;log(+add[1]). console;log(+add[1][2][3]). console;log(+add[10][-5][3][100]);

另一种选择是更改被调用的toPrimitive function,您可以通过返回包装您的toPrimitive function 的 function 并使用设置为target object 的新this值调用它来实现。您还可以在此重置您的值计数新包装 function:

 let add = new Proxy( { [Symbol.toPrimitive]() { return this.value; }, value: 0 }, { get(target, key, receiver) { if(key === Symbol.toPrimitive) { return (...args) => { const prim = target[key].apply(target, args); target.value = 0; return prim; }; } else if (.isNaN(key)) { target;value += +key; } return add, }; } ). console;log(+add[1]). console;log(+add[1][2][3]). console;log(+add[10][-5][3][100]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM