0

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 ?

10
  • There is nothing called class in js Commented Oct 15, 2015 at 11:40
  • @user2181397 wat? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Oct 15, 2015 at 11:41
  • @user2181397 and aside from that reasonably new addition, you can do a similar thing with an old fashioned function. Not a class, but you can still new it to create an instance. Commented Oct 15, 2015 at 11:41
  • @user2181397: Yes, there is. And the term has always been used in a "lower case" form for constructors with associated prototypes. Commented Oct 15, 2015 at 11:42
  • What aspect of performance? Creation of instances or calling of methods on the object? Commented Oct 15, 2015 at 11:44

3 Answers 3

1

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
Sign up to request clarification or add additional context in comments.

Comments

0

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.

6 Comments

actually I suspect the jQuery.extend would be the slowest of them all.
@DoryZidon: Again, it doesn't matter, and in the rare case where it matters, the answer is test it. Also, slowest in what way? Creating instances? Possibly, in theory, not that it will matter. Accessing properties? The result of extend will be faster, in theory, not that it will matter, because it doesn't have to work through the prototype chain to find the properties.
huh indeed ! I would would have fallen in that trap.
I can only properly benchmark it when its done. I want to make a choice while building it. But perhaps I shouldn't, and abstract it away anyway. Something like var ds = getNewDataset().
@T.J.Crowder I agree that performance isn't always the main concern, and in most cases it doesn't matter, however he did ask about performance more than anything :) Maybe in his particular case it does matter. not sure. Either way properties via the prototype chain is not the recommended way to go about it..I suspect parse strigify would work create as it sounds like default values / or Object.create with defaults.
|
0

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

2 Comments

"The old "new" is called prototypical inheritance" So is the new one.
"You can also just clone the object with JSON.parse(JSON.stringify(firstValueObject));" Not if it has anything on it that JSON doesn't support, like Dates or various other objects.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.