gpt4 book ai didi

javascript - 如何链接js函数?

转载 作者:行者123 更新时间:2023-11-30 09:30:56 26 4
gpt4 key购买 nike

让我们想象一下我有一个数字,我想执行一些算术运算示例。

x.add(3).subtract(2).print() // result 1


或者

0.add(3).subtract(2).print() // result 1 (I have no code for this)


目前,我正在尝试以下代码。我想知道是否有更好,更简洁的方法来达到相同的结果,

谢谢



var test = function () {

var i = 0;

var add = function (j) {
i += j;
return this;
};

var subtract = function (j) {
i -= j;
return this;
};

var print = function () {
console.log(i);
};

return {
add: add,
subtract: subtract,
print: print
};
};

var x = test();

x.add(3).subtract(2).print();

最佳答案

这个问题几乎有两个单独的答案:


过于笼统的答案。
适用于一般对象的一般答案。
适用于数字的特定答案。


超一般答案

您可以在任何一个较早的函数返回一个具有另一个函数作为属性的对象(或可以隐式强制转换为对象的对象)时链接函数(松散地称为“方法”)。因此,例如,您可以将.toString().toUpperCase()链接在Date上:

var dt = new Date();
console.log(dt.toString().toUpperCase();


...因为 Date.prototype.toString返回一个字符串,并且字符串具有 toUpperCase方法。

通用答案适用于通用对象

一种常见且有用的模式是拥有一个对象,该对象的方法返回对该相同对象或相同“类型”的另一个对象的引用。 (有时人们说“形状”而不是“类型”,因为JavaScript基本上是无类型的。)例如,jQuery使用此功能产生了很大的效果。 $()返回一个jQuery对象;根据调用的方法,您将返回相同的jQuery对象(例如 each)或一个表示操作结果的新jQuery对象(例如 find)。这种模式对于可变对象尤其是不可变对象都非常有用。

在自己的对象中执行此操作:要返回相同的对象,只需 return this。要返回相同“形状”的新对象,可以使用对对象使用的任何构造机制来创建要返回的新对象。

因此,例如,如果我们在序列的开头添加了一个创建“流”数字的函数,则可以使其可变并每次返回 this



function nstream(val) {
return {
// Our add operation returns this same instance
add: function(n) {
val += n;
return this;
},
// Same with multiply
multiply: function(n) {
val *= n;
return this;
},
// To access the underlying value, we need an accessor
result: function() {
return val;
},
// This provides compatibility with built-in operations
// such as + and *
valueOf: function() {
return val;
}
};
};
// Using only nstream ops:
console.log(nstream(1).add(3).multiply(4).result());
// Implicitly using valueOf at the end:
console.log(nstream(1).add(3) * 4);





或者我们可以使 nstream不变,其中每个操作都返回一个新的 nstream



function nstream(val) {
return {
add: function(n) {
return nstream(val + n);
},
// Same with multiply
multiply: function(n) {
return nstream(val * n);
},
// To access the underlying value, we need an accessor
result: function() {
return val;
},
// This provides compatibility with built-in operations
// such as + and *
valueOf: function() {
return val;
}
};
};
// Using only nstream ops:
console.log(nstream(1).add(3).multiply(4).result());
// Implicitly using valueOf at the end:
console.log(nstream(1).add(3) * 4);





矛盾的是,像这样的不可变对象可能会增加或减少代码中的内存压力,具体取决于它们是否有助于避免防御性复制。例如,如果 nstream是另一个对象的成员,并且您想知道它不能更改,那么如果它可变,则在将其分发给其他代码时必须进行防御性复制;如果它是不可变的,则不必这样做,但是在“修改”它时必须创建副本。但是,不可变对象的成本和收益还是个问题。 :-)

适用于数字的特定答案

尝试在数字上调用方法时,必须将该方法添加到 Number.prototype中。然后,您将让您的方法( addmultiply等)返回操作的结果,该结果为数字将具有您的其他方法。这是一个简单的示例:



Object.defineProperties(Number.prototype, {
add: {
value: function(n) {
return this + n;
}
},
multiply: {
value: function(n) {
return this * n;
}
}
});
console.log(1..add(3).multiply(4));





关于以下几点注意事项:


与扩展内置原型一样,使用 Object.definePropertyObject.defineProperties而不使用 enumerable: true非常重要,这样新属性就无法枚举。 (尽管对于数字来说,这并不是什么大不了的事情。对于数组而言,更是如此。而且,我们完全将普通对象[例如, Object.prototype]留给了其他人。)
..中的 1..add(3)可能看起来很奇怪,但这是您在数字文字上调用方法的两种方式之一。第一个 .是小数点。第二个 .是属性访问器运算符。另一种方法是 (1).add(3),因为数字文字的结尾没有混淆。显然,它没有提供变量: var n = 1; console.log(n.add(3).multiply(4));正常工作。
Number对象与其中的数字基元之间存在相当多的秘密转换:当您访问基元(数字,字符串,布尔值)上的属性(包括函数属性)时,JavaScript引擎会强制将基元转换为其等效的对象类型(Number,String,Boolean),然后在该对象上查找属性。由于它是一个新创建的对象,因此它唯一的属性将来自其原型。因此, 1..add(3)创建一个新的Number对象,然后在该对象上调用 add。在 add中,当我们执行 return this + n时, +将对象强制返回其原始值。当然,JavaScript引擎会在所有可能的地方和所有重要的地方对所有这些进行优化。

关于javascript - 如何链接js函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46338399/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com