I'm trying to add a function to an array of objects, which each object has access to, but which does not need to be added to each object separately.
Let me give you a short example.
Let's say I have an array containing similar objects, each having a property x and a property y:
var objects = [{x:1, y:2},
{x:0, y:5},
{x:3, y:14}
];
I would like to calculate the sum of x
and y
for any of the objects.
First approach:
In order to calculate the sum for a given object, one could pass this object to a predefined function like so:
function xySum1(o) {return o.x + o.y;}
objects[0].x //--> returns 1
objects[0].y //--> returns 2
xySum1(objects[0]) //--> returns 3
This is quite ugly and unsatisfactory, as accessing the x
and y
properties is done differently. Also, my code is in different locations and the function xySum1
is not easily recognizable as being created to act on the objects in the array.
Second approach:
One could loop through the array and add the function as a property to each object:
for (var i=0; i < objects.length; i++) {
objects[i].xySum2 = function() {return this.x + this.y;};
}
Now, the sum is obtained by
objects[0].x //--> returns 1
objects[0].y //--> returns 2
objects[0].xySum2() //--> returns 3
which is much better.
Problems
There are, however, problems with this approach. Firstly, when I add a new element to the array
objects.push({x:5,y:21});
then the sum cannot be calculated before the function has been added to the object
objects[3].xySum2() //-->TypeError
Another problem is that I have many objects, and many functions to add to them. It seems like a waste of good memory space to add each function to each objects individually.
Is there a way to do this more efficiently?
I'm trying to add a function to an array of objects, which each object has access to, but which does not need to be added to each object separately.
Let me give you a short example.
Let's say I have an array containing similar objects, each having a property x and a property y:
var objects = [{x:1, y:2},
{x:0, y:5},
{x:3, y:14}
];
I would like to calculate the sum of x
and y
for any of the objects.
First approach:
In order to calculate the sum for a given object, one could pass this object to a predefined function like so:
function xySum1(o) {return o.x + o.y;}
objects[0].x //--> returns 1
objects[0].y //--> returns 2
xySum1(objects[0]) //--> returns 3
This is quite ugly and unsatisfactory, as accessing the x
and y
properties is done differently. Also, my code is in different locations and the function xySum1
is not easily recognizable as being created to act on the objects in the array.
Second approach:
One could loop through the array and add the function as a property to each object:
for (var i=0; i < objects.length; i++) {
objects[i].xySum2 = function() {return this.x + this.y;};
}
Now, the sum is obtained by
objects[0].x //--> returns 1
objects[0].y //--> returns 2
objects[0].xySum2() //--> returns 3
which is much better.
Problems
There are, however, problems with this approach. Firstly, when I add a new element to the array
objects.push({x:5,y:21});
then the sum cannot be calculated before the function has been added to the object
objects[3].xySum2() //-->TypeError
Another problem is that I have many objects, and many functions to add to them. It seems like a waste of good memory space to add each function to each objects individually.
Is there a way to do this more efficiently?
Share Improve this question asked Apr 20, 2013 at 14:44 ElRudiElRudi 2,2342 gold badges20 silver badges44 bronze badges 8-
6
What about
objects.xySum(0)
? – Bergi Commented Apr 20, 2013 at 14:48 - maybe define a constructor, then the functions will be in the prototype? – user2264587 Commented Apr 20, 2013 at 14:50
-
You can also define a Object.prototype method like this:
Object.prototype.xySum = function() {return typeof this.x !== 'undefined' && typeof this.y !== 'undefined' ? this.x + this.y : undefined;}
. – dfsq Commented Apr 20, 2013 at 14:56 -
@dfsq Extending
Object.prototype
is a very bad practice. – MaxArt Commented Apr 20, 2013 at 14:57 -
@MaxArt It is bad practice only when you don't know what you do. Extending
Object.prototype
can be quite reasonable approach. – dfsq Commented Apr 20, 2013 at 14:59
1 Answer
Reset to default 8Define a class:
function MyObject(x, y) {
this.x = x;
this.y = y;
}
MyObject.prototype = {
xySum2: function() {
return this.x + this.y;
}, x: 0, y: 0
};
Then you can do:
var objects = [
new MyObject(1, 2),
new MyObject(0, 5),
new MyObject(3, 14)
];
objects[0].xySum2(); // 3
objects.push(new MyObject(5, 21));
objects[3].xySum2(); // 26
Alternatively, this is what Bergi probably wanted to say in his ment:
objects.xySum = function(index) {
return this[index].x + this[index].y;
};
This approach is a little bit "dirtier", but also less memory consuming.