I\'m trying to work out the best way to modify an object without writing out a similar object three times. So I have these three objects:
var object1 = {
sta
You can set the common properties to a prototype object. For Example:
function ObjectMaker (typeVal) {
this.type = typeVal;
}
ObjectMaker.prototype.start = "start";
ObjectMaker.prototype.end = "end";
var object1 = new ObjectMaker("1");
var object2 = new ObjectMaker("2");
gives
> object1.start
"start"
> object1.end
"end"
> object1.type
"1"
You could pass in an object to the maker function if number of variables are more.
Since the prototype is shared across objects, you will have a lighter memory footprint than having the same on each object.
Create a function
function createObj(start,end,type){
return {
start : start,
end : end,
type : type
}
}
var object1 = createObj(start,end,1);
var object2 = createObj(start,end,2);
var object3 = createObj(start,end,3);
// if start and end are in scope to the function
function createObj(type){
return {
start : start,
end : end,
type : type
}
}
var object1 = createObj(1);
var object2 = createObj(2);
UPDATE in lieu of the various answers given.
As there are three answers that are all valid I will present speed tests from jperf.com for both creation and object use.
The test can be found Here jsperf.com
Testing in Chrome 47.0.2526.27 on Windows Server 2008 R2 / 7
Creation Tests
Use tests.
As can be seen object.assign
is very slow on when it come to creating object, but holds its own when the objects are being used.
Creating prototypes is about the worst that you can do. Though not as slow as Object assign it seriously suffers when it comes to using objects created this way. Running at below one tenth the speed of the next fastest.
As expected creating objects inline is by far the fastest, though not the most convenient. Yet it was not the fastest when it came to use which is a bit of a surprise.
The fastest for use is creation via function. Though I do not know why and suspect it has to do with V8's optimisation.
Each method has its pros and cons and should be judged on its use and project standards and conventions. In most cases speed is not an issue. Though keep in mind "green coding" favours code that takes the minimum number of cpu cycles, of which execution speed can give a good estimate of. Saving cycles saves power, money, and the lovely world we live on.
Below is the code for the tests. I think I was fair on all four methods.
//================================================================
// Create via Object Assign
var object1 = {
start: start,
end: end,
type: 1
};
var object2 = Object.assign({}, object1, {type: 2});
var object3 = Object.assign({}, object1, {type: 3});
//================================================================
//Create via function
function createObj(type){
return {
start : start,
end : end,
type : type
}
}
var object1 = createObj(1);
var object2 = createObj(2);
var object3 = createObj(3);
//================================================================
//Create via new and prototype
function ObjectMaker (typeVal) {
this.type = typeVal;
}
ObjectMaker.prototype.start = start;
ObjectMaker.prototype.end = end;
var object1 = new ObjectMaker(1);
var object2 = new ObjectMaker(2);
var object2 = new ObjectMaker(3);
//================================================================
// Create inline objects
var object1 = {
start: start,
end: end,
type: 1
};
var object2 = {
start: start,
end: end,
type: 2
};
var object3 = {
start: start,
end: end,
type: 3
};
Use tests.
//================================================================
// Use case for object created with Object.assign
objectB2.end += 1;
objectB2.start += 1;
objectB2.type += 1;
//================================================================
// Use case for object create with new
objectA1.end += 1;
objectA1.start += 1;
objectA1.type += 1;
//================================================================
// Use case for function created object
objectC1.end += 1;
objectC1.start += 1;
objectC1.type += 1;
//================================================================
// Use of literal object create
objectD1.end += 1;
objectD1.start += 1;
objectD1.type += 1;
Setup code
Benchmark.prototype.setup = function() {
// assuming start and end are global
var start = 0;
var end = 10;
// Prototype Method
// object for use test
function ObjectMakerA (typeVal) {
this.type = typeVal;
}
ObjectMakerA.prototype.start = start;
ObjectMakerA.prototype.end = end;
var objectA1 = new ObjectMakerA(1);
// Object assign method
// for use test
var objectB1 = {
start: start,
end: end,
type: 1
};
// object to use
var objectB2 = Object.assign({}, objectB1, {type: 2});
// Anonymous object
// for use test
function createObj1(type){
return {
start : start,
end : end,
type : type
}
}
// object for use test
var objectC1 = createObj1(1);
// Literal object for use test
var objectD1 = {
start: start,
end: end,
type: 1
};
};
I assume you want to create multiple sets of objects with the same start/end pair, but different types.
One approach would be write a function, to which you'd pass a start/end pair, and which returns a function to create an object with a particular type:
function make_creator(start, end) {
return function(type) {
return { start, end, type };
};
}
Now you can create your objects as
var creator = make_creator(start, end);
var object1 = creator(1);
var object2 = creator(2);
var object3 = creator(3);
In this case, you can think of the make_creator
function as "storing" the values of start
and end
for use within the returned closure. It's conceptually related to "storing" them within the "template" proposed in another answer.
Let's consider using prototypes. It's not usually a good idea idea to place values in prototypes. You are likely to shoot yourself in the foot when you try to set the property and end up creating a sort of shadow value on the instance. Any performance (memory) differences will be miniscule unless you have a million objects, and will outweighed by the cost of finding the property on the prototype chain. More importantly, if you want multiple sets of objects with the same start/end pair, you'd have to create separate prototypes for each.
I'm not quite sure why or when we all started worrying quite so much about performance. The bottom line is that the difference in performance (either memory or speed) between any alternatives is going to be miniscule. (The exception is if you are creating millions or tens of millions of these objects.) The guiding principle should be to find an approach which is easy to write, easy to read, and easy to maintain. If you are creating tens of millions of objects, and you determine by profiling your program that this particular area is the bottleneck, then that would be the time to go back and optimize it.
If we are dealing with primitives for all of these properties you can use Object.assign with no worries
var objectTemplate = {
start: start,
end: end,
type: 0
};
var object1 = Object.assign({}, objectTemplate, {type: 1})
object2 = Object.assign({}, objectTemplate, {type: 2}),
object3 = Object.assign({}, objectTemplate, {type: 3});
You don't have to use a template object, you could jump straight into the first object (see previous revision), but as @Blindman67 points out: if you can't guarantee an object will be as you expect then it may be better to use a template which you can guarantee.