2

In the following jsperf: http://jsperf.com/defined-function-vs-in-loop-function/3

You will notice that this code:

for (var i = 0; i < loops; i++) {
   function func(a, b) {
    return a + b;
  };
  func(i, i);
}

Performs on par with this code:

function declaredFn(a, b) {
    return a + b;
};


for (i = 0; i < loops; i++) {
    declaredFni, i);
}

But this code:

for (i = 0; i < loops; i++) {
  var func = function(a, b) {
    return a + b;
  };
  func(i, i);
}

is significantly slower then this code:

var expfunc = function(a, b) {
  return a + b;
};
for (i = 0; i < loops; i++) {  
  expfunc(i, i);
}

Why? What is happening internally?

0

2 Answers 2

8

If you define a function using the function fn() {} declaration, it gets hoisted to the top. Therefore, this code:

for (var i = 0; i < loops; i++) {
   function func(a, b) {
    return a + b;
  };
  func(i, i);
}

is exactly equivalent to this code:

function declaredFn(a, b) { return a + b; };

for (i = 0; i < loops; i++) { declaredFn(i, i); }

because the function declaration gets hoisted to the top.

However, var fn = function() {} expressions do not get hoisted, so you end up defining the function all over on every single loop.

See this answer for more info.

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

4 Comments

It seems to depend on the JS implementation. The test shows that for FireFox it is significantly slower then other versions.
@freakish That's probably because Firefox supports a third type of function creation: function statements. They behave the same as function expressions, so they're created within the loop, not before.
But wouldn't your function statement be a function declaration on any system not supporting the function-statement-extension? In this case it would be a wrong place for a function definition since it's only allowed in Program- or FunctionBody-Level.
@delbertooo Yes that's true. It's wrong in theory but not in practice because most (some) browsers support it (unless you turn on strict mode -- if you turn on strict mode, then declaring a function in a loop using function fn(){} method will give a syntax error).
0

In the snippet

for (i = 0; i < loops; i++) {
  var func = function(a, b) {
    return a + b;
  };
  func(i, i);
}

you are assigning a function to a variable, which will be available in the rest of the current scope. As you are doing this in a loop, the function is defined and assigned many times, therefore consuming more time than in the other cases you mentioned.

7 Comments

"you are assigning a function to a variable" --- even if you remove assignment performance will stay the same
I don't think (but didn't test it), that performance will stay exactly the same, but I guess you are right, that the function definition takes much longer.
"I don't think (but didn't test it), that performance will stay exactly the same" --- well, try then
Sry, didn't really think, when I wrote my last comment: If you remove the assignment, the function is declared only once, if you assign it to a variable, it's defined in every single loop. So it's substantially different code and performance does not stay the same.
it's not an assignment that is slow since assignment is virtually free. Convert it to IIFE, there will be no assignment but it will be slow.
|

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.