JavaScript function order: why is this important?

The original question:

JSHint complains when my JavaScript calls a function defined further on the page than a call to it. However, my page is for the game, and no functions are called until all of this has been downloaded. So why are order functions displayed in my code?

EDIT: I think I found the answer.

http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting

I moan inside. Looks like I need to spend ANOTHER day reordering six thousand lines of code. The learning curve with javascript is not at all steep, but it is very loooooong.

+94
javascript function jslint jshint order
Sep 30 '11 at 10:45
source share
4 answers

tl; dr If you don't name anything until everything boots up, you should be fine.




Change: A review that also covers some ES6 declarations ( let , const ): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_Cheatsheet

This strange behavior depends on

  1. How do you define functions and
  2. When you name them.

Here are some examples.

 bar(); //This won't throw an error function bar() {} foo(); //This will throw an error var foo = function() {} 
 bar(); function bar() { foo(); //This will throw an error } var foo = function() {} 
 bar(); function bar() { foo(); //This _won't_ throw an error } function foo() {} 
 function bar() { foo(); //no error } var foo = function() {} bar(); 

This is because of something called a climb !

There are two ways to define functions: Declaring a function and expressing a function. The difference is annoying and the minute, so let's just say this slightly wrong thing: if you write it as function name() {} , this is an announcement , and when you write it as var name = function() {} (or an anonymous function assigned to return , such things), this is an expression of a function.

First, let's see how variables are processed:

 var foo = 42; //the interpreter turns it into this: var foo; foo = 42; 

Now, how function declarations are processed:

 var foo = 42; function bar() {} //turns into var foo; //Insanity! It now at the top function bar() {} foo = 42; 

The var statements throw the foo creation to the very top, but have not yet assigned a value to it. The function declaration is as follows, and finally, the value is assigned to foo .

What about this one?

 bar(); var foo = 42; function bar() {} //=> var foo; function bar() {} bar(); foo = 42; 

Only the declaration foo moves to the top. Assignment occurs only after a call is made to bar , where it was before all lifts occurred.

And finally, for brevity:

 bar(); function bar() {} //turns to function bar() {} bar(); 

Now, what about functional expressions?

 var foo = function() {} foo(); //=> var foo; foo = function() {} foo(); 

Like ordinary variables, the first foo declared at the highest point in the region, then it is assigned a value.

Let's see why the second example causes an error.

 bar(); function bar() { foo(); } var foo = function() {} //=> var foo; function bar() { foo(); } bar(); foo = function() {} 

As we saw earlier, only the creation of foo raised, the assignment occurs where it appeared in the "original" (un-raised) code. When bar is called, a value is assigned before foo , so foo === undefined . Now in the functional body of bar , as if you are doing undefined() , which causes an error.

+262
Sep 30 '11 at 13:13
source share

The main reason is probably because JSLint only makes one pass in the file, so it does not know that you will define such a function.

If you used function instruction syntax

 function foo(){ ... } 

In fact, it makes no difference where you declare a function (it always behaves as if the declaration was at the beginning).

On the other hand, if your function was set as a regular variable

 var foo = function() { ... }; 

You must ensure that you do not name it before initialization (this can be a source of errors).




Since reordering a ton of code is complex and can be a source of errors in itself, I suggest you look for a workaround. I am sure that you can pre-specify the name of JSLint global variables so that it does not complain about undeclared things.

Comment on the beginning of the file

 /*globals foo1 foo2 foo3*/ 

Or you can use a text box for this. (I also think you can pass this in the arguments to the jslint inner function if you can interfere with it.)

+6
Sep 30 '11 at 13:14
source share

There are too many people who click on arbitrary rules on how to write JavaScript. Most rules are complete garbage.

The hoisting function is a JavaScript function because it is a good idea.

When you have an internal function, which is often the usefulness of internal functions, adding it to the beginning of the external function is an acceptable style of writing code, but it has a drawback that you have to read in detail to get what the external function does.

You must adhere to one principle in your entire code base, or put private functions first or last time in your module or function. JSHint is good for consistency, but you must ABSOLUTELY adjust .jshintrc to suit your needs, DO NOT adjust the source code to other coding concepts of other people.

One coding style that you can see in the wild should be avoided because it does not give you any benefits and only refactoring:

 function bigProcess() { var step1,step2; step1(); step2(); step1 = function() {...}; step2 = function() {...}; } 

This is exactly what needs to be avoided. Just learn the language and use its strengths.

+3
Apr 18 '15 at 14:10
source share

Declaring only a function is not declared an expression (assignment) function.

+1
Dec 13 '17 at 5:46 on
source share



All Articles