提问人:jeweler23 jeweler23 提问时间:11/16/2023 最后编辑:Mister Jojojeweler23 jeweler23 更新时间:11/17/2023 访问量:107
转换为原始 [duplicate]
Convert to primitive [duplicate]
问:
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。我真的不明白转换为原语是如何发生的,以及为什么要通过函数编写它
答:
Function 的默认函数将返回字符串化函数。换句话说:函数的原始值是......手头的功能。要显示 中的(中间的、封闭的)基元值,您需要重写 的函数。toString
currentSum
f
toString
f
也许下一个片段澄清了这一点。
注意:第一个代码段中的最后一个代码使用 .为什么有效?这在 MDN 中进行了解释:console.log
+sum(1)(2)(3)
一元加号对其操作数执行数字强制,对于大多数没有@@toPrimitive的对象,这意味着调用其 valueOf()。但是,如果对象没有自定义 valueOf() 方法,则基本实现将导致忽略 valueOf(),并改用 toString() 的返回值。
// note: default values for parameters added
function sum(startValue = 0) {
// [currentSum] is enclosed for further operations
let currentSum = startValue;
function f(value = 0) {
currentSum += value;
// returning the function
// makes it possible to call
// it again with a new value
return f;
}
// f.toString would deliver the stringification
// of the function f. To retrieve the value of
// [currentSum] that should be overridden.
f.toString = function() {
return currentSum;
};
// return the function with the overridden
// toString method
return f;
}
function someFunction() {
return `Hi! I am the result of someFunction()`;
}
// the primitive value of [someFunction] is ...
// a function, so you can call it using
// its valueOf
console.log(`someFunction.valueOf()(): ${someFunction.valueOf()()}`);
// a functions default 'toString' returns
// the string representation of the function
console.log(`someFunction.toString(): ${someFunction.toString()}`);
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}`);
// comparisons with a Number
// no type coercion (==)
console.log(`six == 16 ${six == 16}`);
// use toString for type coerced comparison with Number
console.log(`six.toString() === 16 ${six.toString() === 16}`);
// [six] is still a function, so
console.log(`six === 16 ${six === 16}`);
// to compare a [sum] result with a number
// with type coercion (===)
// it can be converted to Number (+)
// see answer text for explanation.
console.log(`+sum(1)(2)(3) === 6 ${+sum(1)(2)(3) === 6}`);
.as-console-wrapper {
max-height: 100% !important;
}
为了好玩:因为 a 只是另一个对象
,你也可以用你自己的 'value' 方法扩展它。在这种情况下,您必须显式调用扩展方法来检索包含的值。Function
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;
}
更进一步的步骤是将方法转换为 getters(这样你就不需要使用括号了),或者将你自己的 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;
}
评论
sum
sum
toString
Function.toString
sum
Q&R:
-1- 什么是?
在 JS 中,一切都是 Object(即使它们被定义为函数)。sum()
-2- 什么是?
它是 里面的局部值。
此局部值只能在 的作用域内更改。currentSum
sum()
sum()
-3- 什么是?
一个对象函数,它添加他的参数值
并返回自身(一个函数)f
currentSum
-4- 什么是?
它是对象上的重载方法,它重载了 Deault(JavaScript 是一个原型对象
模型)f.toString
f
Object.prototype.toString()
-5- 发生了什么?
有不同的步骤:console.log(sum(1)(2)(3));
__a) -> currentSum = 1,并查看 sum() 的最后一行
__b) -> currentSum += 2 和 __c) -> currentSum += 3 和
__d) => 调用 的方法。let fctA = sum(1)
return f
let fctB = fctA(2)
return f
let fctC = fctA(3)
return f
let D = fctC.toString()
toString()
f
let fctA = sum(1);
let fctB = fctA(2);
let fctC = fctA(3);
let D = fctC.toString(); //--> sum is: 6
console.log( D );
function sum(a)
{
let currentSum = a;
function f(b)
{
currentSum += b;
return f;
}
f.toString = function()
{
return `sum is: ${currentSum}`;
};
return f;
}
但是我们如何进入[?],因为在最后一个参数之后,我们又回来了
f.toString
f
是的,它仍然返回.
但也是一个 JS 对象,它 [本身] 有一个名为 的 [默认] 方法。
由于此方法已存在于所有 JS 对象中,因此默认情况下会覆盖此方法。f
f
toString
f.toString
--
编写 js 函数的方法至少有 2 种:(1)
(2) function foo() {...}
var foo = function() {...}
在此代码中,这是方式 (2)。
但也意味着 -> 是 Object 上的一种方法。f.toString = function() {...}
f.toString
toString
f
--
也许这可能会有所帮助
console.log( sum(1)(2)(3) );
║ ┗┳━┛ ┃ ┃
║ A ▉────┃──┃──🭬let currentSum = 1;
║ ┃ ┃ ┃ return f;
║ ┗━┳━━┛ ┃
║ B ▉─────┃──🭬currentSum += 2;
║ ┃ ┃ return f;
║ ┗━━┳━━┛
║ C ▉─────🭬currentSum += 3;
║ ║ return f;
║ ║
D╙──────────╨🭬call prototype method of function.toString()
find overiding method: f.toString()
return `sum is: ${currentSum}`;
评论
a=b*c*d*e
M1=b*c
M2=M1*d
a=M2*d
a=b*c*d*e
toString
上一个:将文本作为数据帧读入 R
评论
sum(1)(2)(3)
不返回 。它返回一个函数对象,当用于例如 可以通过 自动转换为字符串。所以可以打印 6.6
console.log
toString
console.log(sum(1)(2)(3))
.toString()
是任何 JS 对象的默认方法。此闭包使此方法重载。所以用这个方法来显示信息console.log()
.tostring()