I'm trying to do something I don't remember/find if it is possible in javascript.
I have an object constructor "Point" and I want to know if it possible to, for example, sum two different objects like bellow.
function Point(x, y) {
this.x = x;
this.y = y;
}
a = new Point(1,2);
b = new Point(2,3);
c = a+b;
console.log('a: ', a)
console.log('b: ', b)
console.log('c: ', c)
I'm trying to do something I don't remember/find if it is possible in javascript.
I have an object constructor "Point" and I want to know if it possible to, for example, sum two different objects like bellow.
function Point(x, y) {
this.x = x;
this.y = y;
}
a = new Point(1,2);
b = new Point(2,3);
c = a+b;
console.log('a: ', a)
console.log('b: ', b)
console.log('c: ', c)
a = Point {x: 1, y: 2}
b = Point {x: 2, y: 3}
Expected result: c = Point {x: 3, y: 5}
Share
Improve this question
edited Sep 19, 2018 at 8:33
Raghav Garg
3,7072 gold badges26 silver badges33 bronze badges
asked Sep 19, 2018 at 8:27
JóniJóni
3741 gold badge3 silver badges16 bronze badges
5
-
2
You would create a custom method
a.add(b)
, within which you do the summing with the appropriate behaviour for that type of object. – deceze ♦ Commented Sep 19, 2018 at 8:28 - That was quick, thanks :) So, something like this right? Point.prototype.add = function(point2){ return new Point(this.x + point2.x, this.y + point2.y) } a.add(b); – Jóni Commented Sep 19, 2018 at 8:32
-
1
Yeah, but I would suggest you to use
Point.add(obj1, obj2)
rather thanobj1.add(obj2)
. The first way just looks cleaner. – Raghav Garg Commented Sep 19, 2018 at 8:36 - Ok, got it. thanks – Jóni Commented Sep 19, 2018 at 8:38
-
@Raghav That is not really OOP then. Using
a.add(...)
, you can subclassa
with some other geometric shape for which adding a point would also make sense. WithPoint.add(...)
you hardcode the behaviour to only points. – deceze ♦ Commented Sep 19, 2018 at 8:43
5 Answers
Reset to default 4function sumOfObjects(Obj1, Obj2){
var finalObj = {};
this.keys(Obj1).forEach(value =>{
if (Obj2.hasOwnProperty(value)) {
finalObj[value] = Obj1[value] + Obj2[value]
}
});
return finalObj;
}
You can create a function for this. A function that should accept the two points should be enough, then in the implementation create a new Point that contains the sum of each property.
function addPoint(pointA, pointB) {
const newX = pointA.x + pointB.x;
const newY = pointA.y + pointB.y;
return new Point(newX, newY);
}
This is the most basic code you can do for it, but for instance there are other approaches such as allowing multiple parameters then generating the sum for all of it would require a different approach as well.
You can do something like below code. We are adding a static method on Point function which will add two objects and return new object.
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.add = function(a, b) {
const x = a.x + b.x;
const y = a.y + b.y;
return new Point(x, y)
}
a = new Point(1,2);
b = new Point(2,3);
c = Point.add(a, b)
console.log('a: ', a)
console.log('b: ', b)
console.log('c: ', c)
So, it turns out that is possible to do it. It just isn't advisable to do it.
I found the solution after some more digging in an old post: Fake operator overloading in JavaScript article and git Fake operator overloading for JavaScript code
credit to Axel Rauschmayer, the author
function Point(x, y) {
if (arguments.length === 0) {
x = 0;
y = 0;
} else if (arguments.length !== 2) {
throw new Error("Need either 0 or 2 arguments");
}
this.x = x;
this.y = y;
}
//-------------- Operator overloading
Point.operands = [];
Point.prototype.valueOf = function() {
Point.operands.push(this);
// Lowest natural number x where the following are all different:
// x + x, x - x, x * x, x / x
return 3;
}
Object.defineProperty(Point.prototype, "_", {
set: function(value) {
var ops = Point.operands;
var operator;
if (ops.length >= 2 && (value === 3 * ops.length)) {
operator = this.setAdd;
} else {
throw new Error("Unsupported operation (code " + value + ")");
}
Point.operands = []; // reset
return operator.apply(this, ops);
},
get: function() {
return this.toString();
}
});
//-------------- Operator implementations
Point.prototype.setAdd = function(first) {
this.x = first.x;
this.y = first.y;
[].slice.call(arguments, 1).forEach(function(op) {
this.x += op.x;
this.y += op.y;
}, this);
return this;
}
//-------------- Various helpers
Point.prototype.toString = function() {
return "Point(" + this.x + ", " + this.y + ")";
}
Point.prototype.equals = function(other) {
return this.x === other.x && this.y === other.y;
}
//-------------- Testing it
var p = new Point();
var a = new Point(1, 2);
var b = new Point(4, 3);
p._ = a + b;
console.log(p); // Point {x: 5, y: 5}
You may not simply use the +
operator. In javascript an object will be converted to primitive(string or number) if it is in an AdditiveExpression.
So there is not a clean way to sum properties of two objects in javascript, you may need to create an additional function.