commonpike
commonpike

Reputation: 11185

Performance of javascript Class definitions vs Objects

I'm writing a javascript application that extensively uses a particular form of dataset, like

{ foo: 'foo', bar: 'bar', quz: { baz : 'baz' }}

It's only data, but it's nested. There is no static data.

I want to create a template for that dataset to keep the code clean. I can either put a template object somewhere and clone that everytime, like (using jquery just for the example)

var ds = jQuery.extend(true, {}, config.dataset);

or I can create a 'Class' or function prototype that I can call with

var ds = new Dataset();

What performs best ? If using the new constructor, is there a difference between a Class and a function definition ?

Upvotes: 0

Views: 3931

Answers (3)

commonpike
commonpike

Reputation: 11185

Inspired by TJCrowder's answer here, I came up with a third option

function newDataset( return { foo: 'foo', bar: 'bar', quz: { baz : 'baz' }});
var ds = newDataset();
  • it centralizes the definition of the dataset, which was the purpose
  • it always creates a new object, without the risk of sharing data members
  • i can always change the internal mechanics later and benchmark that

Upvotes: 1

Dory Zidon
Dory Zidon

Reputation: 10719

There are a few ways to do this, not only the two you specified, you can also use pure JS prototypes, when comparing all three it seems pure js would be the fastest.

Few things:

  1. Please note that using Classes is ES6 which is not widely supported by all browsers yet.
  2. The old "new" is called prototypical inheritance, if you use that (which I would suggest you do, or the new format of it using Object.create) be careful of sharing data members between classes.
  3. You can also just clone the object with JSON.parse(JSON.stringify(firstValueObject));
  4. If you choose Object.create (ES5) you can define default values: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create

http://jsperf.com/jquery-class-create-vs-pure-js-function/3

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1074355

The answer to "What performs best?", in general, is: Worry about it if and when you actually have a performance problem.

The answer to "What performs best?" in JavaScript is:

  1. See the general answer, and

  2. It depends, test on your target JavaScript engines (browsers, etc.)

Let's ignore performance, though, and look at the alternatives you gave.

Implementing a DataSet "class" (constructor and associated prototype, either with the new or old syntax) would be quite complicated and give you virtually no benefit for the use case you describe. You have a nested object structure:

{ foo: 'foo', bar: 'bar', quz: { baz : 'baz' }}

...and so if you used that as a prototype, it would be very easy to get cross-talk between instances. Example:

// Demonstrating cross-talk
function DataSet() {
}
DataSet.prototype = { foo: 'foo', bar: 'bar', quz: { baz : 'baz' }};

var d1 = new DataSet();
var d2 = new DataSet();
d1.quz.baz = "updated";
document.body.innerHTML = d2.quz.baz; // "updated" - huh?!

To avoid that, you'd have to make a copy of the quz property on construction:

function DataSet() {
    this.quz = jQuery.extend(true, {}, this.quz);
}

Then you have to remember to do that any time you add new nested objects in the prototype.

From what you've told us, the simplest solution is just to use your first example with jQuery.extend.

Upvotes: 0

Related Questions