Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript: variable assignment in functions

Tags:

javascript

Consider these two blocks:

Block A

obj = {
    a: 1,
    b: 2,
    c: 3,
    f: function() {
        alert(this.a);
        alert(this.b);
        alert(this.c);
    }
}

Block B

obj = {
    a: 1,
    b: 2,
    c: 3,
    f: function() {
        var a = this.a;
        var b = this.b;
        var c = this.c;
        alert(a);
        alert(b);
        alert(c);
    }
}

Is one way more correct/efficient than the other? Of course, this is a condensed example - in my code there are more variables, and what I am trying to do is to save time by not typing this.varName every time in the functions by reassigning the variables for the current function's scope. It works, but is it correct?

EDIT: Just to clarify, the variables will be used extensively throughout the function(s). General consensus seems to be that for this, reassignment through local scope is the way to go.

like image 777
Alex Avatar asked Aug 15 '11 17:08

Alex


5 Answers

Depends. If you're only going to use the value one time, it doesn't make sense to add the overhead of storing and then retrieving the value. If, on the other hand, you reference the value several times in the scope of the function, it makes sense to only fetch it once.

like image 106
Jeremy Holovacs Avatar answered Oct 18 '22 00:10

Jeremy Holovacs


In

f: function() {
    a = this.a;
    b = this.b;
    c = this.c;
    alert(a);
    alert(b);
    alert(c);
}

not only is the global assignment and lookup less efficient, but you are polluting the global scope because a = this.a is assigning to the global a.

EDIT:

Let's assume that this.a and this.b cause a getter to fire, and alert(a) causes a call to the toString method of the value of a.

There is an order of operation difference between

var a = this.a, b = this.b;
alert(a); alert(b);

which does (get a, get b, a toString, b toString) and

alert(this.a); alert(this.b);

which does (get a, a toString, get b, b toString) and

There may be a good reason to prefer one order of operations to the other, but efficiency-wise, the second is probably better.

Because of the order of operations difference, you should not rely on a semantics-preserving JavaScript minifier to optimize the first to the second when there is only one use of the member.

like image 40
Mike Samuel Avatar answered Oct 18 '22 01:10

Mike Samuel


It all depends. If you only access the property once in your function, the first is faster. If you access it more than once, it is faster to use modified version the second code chunk.

Changing the second version to declare a, b, and c as local vars of f() will avoid multiple scans of the scope chain and traversal of this - again, this is if you need to access those properties multiple times.

like image 36
JAAulde Avatar answered Oct 18 '22 00:10

JAAulde


Nicholas Zakas mentions this as a way to speed up your JavaScript. From the summary of the video:

Similar to global variables, performance can be improved by creating local variables to hold object properties and array items that are referenced multiple times. Also, keep in mind that deeper object property and array item lookup (e.g., obj.name1.name2.name3) is slower.

like image 23
sdleihssirhc Avatar answered Oct 18 '22 02:10

sdleihssirhc


The first way if more Efficient relatively, since in the second way, you are making a copy of the variables, and hence one extra statement for all the variables and more memory space will be occupied(both by the code and the variables).

like image 1
Pheonix Avatar answered Oct 18 '22 00:10

Pheonix