这是我能想到的措辞这个问题,因为这个JavaScript“类”的定义的最佳方式:
var Quota = function(hours, minutes, seconds){
if (arguments.length === 3) {
this.hours = hours;
this.minutes = minutes;
this.seconds = seconds;
this.totalMilliseconds = Math.floor((hours * 3600000)) + Math.floor((minutes * 60000)) + Math.floor((seconds * 1000));
}
else if (arguments.length === 1) {
this.totalMilliseconds = hours;
this.hours = Math.floor(this.totalMilliseconds / 3600000);
this.minutes = Math.floor((this.totalMilliseconds % 3600000) / 60000);
this.seconds = Math.floor(((this.totalMilliseconds % 3600000) % 60000) / 1000);
}
this.padL = function(val){
return (val.toString().length === 1) ? "0" + val : val;
};
this.toString = function(){
return this.padL(this.hours) + ":" + this.padL(this.minutes) + ":" + this.padL(this.seconds);
};
this.valueOf = function(){
return this.totalMilliseconds;
};
};
和下面的测试设置的代码:
var q1 = new Quota(23, 58, 50);
var q2 = new Quota(0, 1, 0);
var q3 = new Quota(0, 0, 10);
console.log("Quota 01 is " + q1.toString()); // Prints "Quota 01 is 23:58:50"
console.log("Quota 02 is " + q2.toString()); // Prints "Quota 02 is 00:01:00"
console.log("Quota 03 is " + q3.toString()); // Prints "Quota 03 is 00:00:10"
是否有隐式创建的任何方式q4
的Quota
使用加法运算符如下对象...
var q4 = q1 + q2 + q3;
console.log("Quota 04 is " + q4.toString()); // Prints "Quota 04 is 86400000"
而不是诉诸于...
var q4 = new Quota(q1 + q2 + q3);
console.log("Quota 04 is " + q4.toString()); // Prints "Quota 04 is 24:00:00"
如果没有什么这方面的最佳做法建议制作自定义数值JavaScript对象通过算术运算符组合的?
Answer 1:
据我所知,使用Javascript(至少现在存在)不支持运算符重载。
我建议最好是从其他几个人制作新的配额对象的一类方法。 下面是我的意思一个简单的例子:
// define an example "class"
var NumClass = function(value){
this.value = value;
}
NumClass.prototype.toInteger = function(){
return this.value;
}
// Add a static method that creates a new object from several others
NumClass.createFromObjects = function(){
var newValue = 0;
for (var i=0; i<arguments.length; i++){
newValue += arguments[i].toInteger();
}
return new this(newValue)
}
并使用它,如:
var n1 = new NumClass(1);
var n2 = new NumClass(2);
var n3 = new NumClass(3);
var combined = NumClass.createFromObjects(n1, n2, n3);
Answer 2:
很不幸的是,不行。
对于回退,如果你安排的返回值,可以使用方法链接
var q4 = q1.plus(p2).plus(q3);
Answer 3:
既然每个人都向下投我的其他答案,我想后的概念代码是实际可行的意图证明。
这已经在Chrome和IE浏览器进行了测试。
//Operator Overloading
var myClass = function () {
//Privates
var intValue = Number(0),
stringValue = String('');
//Publics
this.valueOf = function () {
if (this instanceof myClass) return intValue;
return stringValue;
}
this.cast = function (type, call) {
if (!type) return;
if (!call) return type.bind(this);
return call.bind(new type(this)).call(this);
}
}
//Derived class
var anotherClass = function () {
//Store the base reference
this.constructor = myClass.apply(this);
var myString = 'Test',
myInt = 1;
this.valueOf = function () {
if (this instanceof myClass) return myInt;
return myString;
}
}
//Tests
var test = new myClass(),
anotherTest = new anotherClass(),
composed = test + anotherTest,
yaComposed = test.cast(Number, function () {
return this + anotherTest
}),
yaCComposed = anotherTest.cast(Number, function () {
return this + test;
}),
t = test.cast(anotherClass, function () {
return this + anotherTest
}),
tt = anotherTest.cast(myClass, function () {
return this + test;
});
debugger;
如果有人会这么好心给一个技术的解释,为什么这还不够好,我会很高兴地听到吧!
Answer 4:
第二个建议:
var q4 = Quota.add(q1, q2, q3);
Answer 5:
最近,我这篇文章在: http://www.2ality.com/2011/12/fake-operator-overloading.html 。
它介绍了如何重新定义对象的valueOf方法做一些像运营商在JavaScript超载。 好像你真的只能上操作在对象上执行操作的突变,所以你想要的东西就不会做。 它的有趣仍然寿。
Answer 6:
你可以隐式转换为整数或字符串,你的对象
如果期望的JavaScript一个数字或字符串对象仅隐式转换。 在前一种情况下,转换需要三个步骤:
1.-调用的valueOf()。 如果结果是原始(未对象),然后使用它,并将其转换为一个数字。
2:否则,调用toString()。 如果结果是原始的,使用它,将其转换为一个数字。
3.-否则,抛出一个TypeError。 例如,对于步骤1:
3 * {的valueOf:函数(){返回5}}
如果JavaScript的转换为字符串,步骤1和2被交换:的toString()首先尝试,的valueOf()秒。
http://www.2ality.com/2013/04/quirk-implicit-conversion.html
Answer 7:
Paper.js这样做,例如用加分( 文档 ):
var point = new Point(5, 10);
var result = point + 20;
console.log(result); // {x: 25, y: 30}
但它确实使用其自己的IT 自定义脚本解析器 。
Answer 8:
我不知道为什么人们继续回答没有这个问题!
这里绝对是一个办法,我将与你不必成为John Resig的了解一个非常非常小的脚本大纲...
之前,我这样做,我也将指出,在JavaScript中你的构造会的工作方式是通过检查数组或迭代“论据”的文字。
例如,在我的我的“类”的构造我会遍历arugments,确定潜在的arugments的类型和智能地处理它。
这意味着,如果你通过一个数组我会迭代arugments找到一个数组,然后遍历数组取决于类型数组中的元素做进一步的处理。
例如 - >新SomeClass的([instanceA,instanceB,instanceC])
但是你们正在寻找一个更“C”式的方法来操作符重载这实际上可以achived违背populare信念。
这是我所使用MooTools的该做的荣誉运算符重载创建的类。 在普通的旧的JavaScript你只需使用相同的toString方法只能将其连接到直接原型实例。
我显示这个方法主要的原因是因为我不断地读课文其中指出该功能是“不可能”来模拟。 没有什么是不可能只配备充分和困难我将在下面显示此...
//////
debugger;
//Make a counter to prove I am overloading operators
var counter = 0;
//A test class with a overriden operator
var TestClass = new Class({
Implements: [Options, Events],
stringValue: 'test',
intValue: 0,
initialize: function (options) {
if (options && options instanceof TestClass) {
//Copy or compose
this.intValue += options.intValue;
this.stringValue += options.stringValue;
} else {
this.intValue = counter++;
}
},
toString: function () {
debugger;
//Make a reference to myself
var self = this;
//Determine the logic which will handle overloads for like instances
if (self instanceof TestClass) return self.intValue;
//If this is not a like instance or we do not want to overload return the string value or a default.
return self.stringValue;
}
});
//Export the class
window.TestClass = TestClass;
//make an instance
var myTest = new TestClass();
//make another instance
var other = new TestClass();
//Make a value which is composed of the two utilizing the operator overload
var composed = myTest + other;
//Make a value which is composed of a string and a single value
var stringTest = '' + myTest;
//////
观察在XDate的文档页面最近这种命名法显示: http://arshaw.com/xdate/
在这种情况下,我相信这是居然连easer,他可以使用Date对象的原型才达到相同。
尽管如此方法我已为应描绘利用这种风格的一个范例。
编辑:
我有一个完整的实现在这里:
http://netjs.codeplex.com/
随着其他商品。
Answer 9:
我做了一个脚本,它操作符重载在JavaScript中。 这不是简单的做工作,所以有一些怪癖,但。 我将穿越后从项目页面在这里的告诫,否则你可以找到在底部的链接:
计算结果必须传递给新的对象,所以不是(P1 + P2 + P3)你必须做新的点(P1 + P2 + P3),(给你的用户定义的对象被命名为“点”)。
只有+, - ,*和支持/,第五计算opperator%是没有的。 如预期强迫字符串(“” + P1)和比较(P1 == P2)将无法正常工作。 新的功能,应该为这些目的如果需要的话,像(p1.val == p2.val)来构建。
最后计算出答案所需要的计算资源与项数平方增加。 因此,只有6方面是允许在每一个默认计算链(虽然这可增大)。 对于较长的计算链比,分割计算起来,如:新的点(新点(P1 + P2 + P3 + P4 + P5 + P6)+新点(P7 + P8 + P9 + P10 + P11 + P12))
在Github的页面 。
Answer 10:
除了那些已经被说:覆盖.valueOf()可以帮助产生相当强大的运算符重载。 在验证的概念Fingers.js LIB您可以在.NET样式添加事件侦听器:
function hi() { console.log("hi") }
function stackoverflow() { console.log("stackoverflow") }
function bye() { console.log("bye") }
on(yourButton).click += hi + stackoverflow;
on(yourButton).click -= hi - bye;
核心思想是暂时替代的valueOf当()被调用:
const extendedValueOf = function () {
if (handlers.length >= 16) {
throw new Error("Max 16 functions can be added/removed at once using on(..) syntax");
}
handlers.push(this); // save current function
return 1 << ((handlers.length - 1) * 2); // serialize it as a number.
};
返回数可以接着使用处理器阵列反序列化回功能。 更重要的是这是可能的提取物位值从终值(FUNC1 + FUNC2 - FUNC3),以便有效地,你能理解添加和除去哪些功能是什么功能。
您可以检查出源的github和玩耍这里演示 。
完整的解释存在这文章 (它是AS3,坚韧的,因为它是ECMAScript中它会为JS工作,要么)。
Answer 11:
对于一些有限的使用情况下,你可以拥有运营商“超载”的效果:
function MyIntyClass() {
this.valueOf = function() { return Math.random(); }
}
var a = new MyIntyClass();
var b = new MyIntyClass();
a < b
false
a + b
0.6169137847609818
[a, b].sort() // O(n^2) ?
[myClass, myClass]
function MyStringyClass() {
this.valueOf = function() { return 'abcdefg'[Math.floor(Math.random()*7)]; }
}
c = new MyStringyClass();
'Hello, ' + c + '!'
Hello, f!
上面的代码是免费的在MIT许可下使用。 因人而异。
文章来源: Overloading Arithmetic Operators in JavaScript?