7

In reading this http://www.html5rocks.com/en/tutorials/speed/v8/ it makes sense that changing the type of variable at runtime forces browsers to work harder than when keeping them consistent.

So does that mean this is not a good idea:

 var x = { alpha: null, bravo: null, charlie: null, delta: null, echo: null } x.alpha = {a:1, b:true} x.bravo = 13 x.charlie = true x.delta = [1,2,3] x.echo = 'abc' 

Because here the types started as null, then got changed to object, int, boolean arrary.

And for the sake of simplicity, afterwards these types never change.

Or is this more efficient:

 var x = { alpha: {}, bravo: 0, charlie: false, delta: [], echo: '' } x.alpha = {a:1, b:true} x.bravo = 13 x.charlie = true x.delta = [1,2,3] x.echo = 'abc' 

I can understand changing types from say a number to an array is not a good idea. What about changing from null into a type once during execution?

The books and blogs I have read mostly say to define variables with null (as opposed to undefined) when the values are only known at runtime. At face value, this seems wrong, as defining with their empty type avoids a type change.

5
  • null is of type object Commented Jan 25, 2014 at 8:07
  • that's good, because it's a lot easier to check if something is null rather than {} Commented Jan 25, 2014 at 8:08
  • actually you cannot check against {}, well you can but you would always get false, as that creates a new object on the fly, for instance {} === {} evaluates to false. Commented Jan 25, 2014 at 8:15
  • Yeah, I know...it is a lot harder and seems like longer to check for an empty object. Commented Jan 25, 2014 at 8:19
  • I'm not sure about the performance issues but an alternative would maybe to declare x as an empty object and only add certain properties if they have a real value. Then you can check whether a property is set or not using .hasOwnProperty() for instance. Commented Jan 25, 2014 at 8:43

2 Answers 2

6

Intrigued by this question, I set up a fiddle to look at the performance of some different use cases.

Open console to view data in this fiddle
http://jsfiddle.net/kmiklas/MFNak/14/

  • There seems to be little difference between no initialization, initializing to null, and initializing to a number.
  • With the exception of numbers, there is a perf loss by initializing variables to the intended type (second example in original post).
  • From these data, it stands to reason that initializing to nothing is the best option.

Typical results from Chrome v32 with n = 100000000:

number no init: 97.070ms number init to null: 98.023ms number init to number: 97.246ms array no init: 457.494ms array init to null: 458.301ms array init to number: 455.166ms array init to array: 836.710ms object no init: 508.268ms object init to null: 512.312ms object init to object: 754.562ms number to object: 455.733ms array to object: 834.169ms object to array: 751.498ms ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

Code is rather lengthy, but included below, per SO requirements.

n = 100000000; console.time("number no init"); for (var i = n; i >= 0; i--) { var x; x = 42; }; console.timeEnd("number no init"); console.time("number init to null"); for (var i = n; i >= 0; i--) { var x = null; x = 42; }; console.timeEnd("number init to null"); console.time("number init to number"); for (var i = n; i >= 0; i--) { var x = 1; x = 42; }; console.timeEnd("number init to number"); console.time("array no init"); for (var i = n; i >= 0; i--) { var a; a = [42]; }; console.timeEnd("array no init"); console.time("array init to null"); for (var i = n; i >= 0; i--) { var a = null; a = [42]; }; console.timeEnd("array init to null"); console.time("array init to number"); for (var i = n; i >= 0; i--) { var a = 1; a = [42]; }; console.timeEnd("array init to number"); console.time("array init to array"); for (var i = n; i >= 0; i--) { var a = []; a = [42]; }; console.timeEnd("array init to array"); console.time("object no init"); for (var i = n; i >= 0; i--) { var a; a = {n:42}; }; console.timeEnd("object no init"); console.time("object init to null"); for (var i = n; i >= 0; i--) { var a = null; a = {n:42}; }; console.timeEnd("object init to null"); console.time("object init to object"); for (var i = n; i >= 0; i--) { var a = {}; a = {n:42}; }; console.timeEnd("object init to object"); console.time("number to object"); for (var i = n; i >= 0; i--) { var a = 1; a = {n:42}; }; console.timeEnd("number to object"); console.time("array to object"); for (var i = n; i >= 0; i--) { var a = []; a = {n:42}; }; console.timeEnd("array to object"); console.time("object to array"); for (var i = n; i >= 0; i--) { var a = {}; a = [42]; }; console.timeEnd("object to array"); console.log('~~~~~~~~~~~~~~~~~~~~~~~~~~~'); 

Edit:

Keep in mind that I only tested in Chrome 32. To accurately draw this conclusion, it would be best to load this fiddle and see results in the more popular desktop and mobile browsers; particularly, IE and Safari Mobile.

Sign up to request clarification or add additional context in comments.

1 Comment

Keep in mind that I only tested in Chrome 32. To accurately draw this conclusion, it would be best to load this fiddle and see results in the more popular desktop and mobile browsers; particularly, IE and Safari Mobile.
3

At initialization, all javascript variables are hoisted to the top of the scope with the value of undefined. It's not until a variable's value is assigned that a specific type can be assigned.

So what you're doing here is effectively reassigning the value and type of your variable twice. The performance cost is likely negligible, however the preferred practice to declare an object whose values are not known is with an object literal:

var x = {}; 

If you try to access a property of an object that doesn't exist, you'll get undefined (which is just as easy to test for as null). However, if as you say the properties are known before runtime then there's no reason not to assign those properties straight away, so...

 x.alpha = {a:1, b:true} x.bravo = 13 x.charlie = true x.delta = [1,2,3] 

becomes...

var x = { alpha: {a:1, b:true}, bravo: 13, charlie: true, delta: [1,2,3] }; 

9 Comments

Most of the time I do not know the value of these variables until runtime. I know the type will not change. So should all unknown variables be declared as {} even if you know later in the code it will be an integer?
No, only variables that you know are going to be objects that you'll later assign properties. If you don't know what the type is going to be, you can just declare a variable without a value, var x;
What about an integer? I cannot assign a value when declared, so do this: x={alpha: undefined} ??
@monners what if x has to be set to an object, but not all of its property values are known at that time?
@BrianMcGinity just don't define the properties whose future values you don't know.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.