让图像我有一个数字,我想执行一些算术运算示例。
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();

答案 0 :(得分:4)
这个问题几乎有两个独立的答案:
超常规答案。
适用于对象的一般答案,呃,一般。
适用于数字的具体答案。
你可以在早期函数返回一个对象(或者可以被隐式强制转换为对象的东西)的任何时候链接函数,该对象具有另一个函数作为属性(松散地,“方法”)。例如,您可以在.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
。然后你有你的方法(add
,multiply
等)返回操作的结果,这是一个数字将有你的其他方法。这是一个简单的例子:
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.defineProperty
或Object.defineProperties
而不使用enumerable: true
非常重要,因此新属性不可枚举。 (虽然有数字但这并不是什么大问题。对于数组来说更是如此。而且我们完全保留普通对象[例如,Object.prototype
]。)..
中的1..add(3)
可能看起来很奇怪,但它是您在数字文字上调用方法的两种方法之一。第一个.
是小数点。第二个.
是属性访问者运算符。另一种方式是(1).add(3)
因为数字文字结束时没有混淆。显然,这并没有提出变量:var n = 1; console.log(n.add(3).multiply(4));
工作得很好。1..add(3)
创建一个新的Number对象,然后在该对象上调用add
。当我们执行add
时return this + n
内,+
会将对象强制回原始值。当然,所有这些都在可能的情况下进行了优化,并且在JavaScript引擎的重要位置。答案 1 :(得分:0)
您可以向Number
对象添加一些原型,并使用浮点和点的方法调用该值。
不建议更改标准对象的标准,因为它们可能会导致对代码的误解。
Number.prototype.add = function (v) { return this + v; };
Number.prototype.multiply = function (v) { return this * v; };
console.log(1..add(2).multiply(4)); // 12
答案 2 :(得分:0)
只要返回上一个方法,就可以链接方法。 所以,在这种情况下,你需要创建一个"类" thas拥有所有需要的方法,然后返回一个"实例"所有这些课程中的那一课。
var myNum = function(n) {
var num = n;
this.add = function(a) {
var b = n+a;
return new myNum(b) ;
}
}