Programing

JavaScript 함수 순서 : 왜 중요한가요?

lottogame 2020. 8. 18. 08:09
반응형

JavaScript 함수 순서 : 왜 중요한가요?


원래 질문 :

JSHint는 내 JavaScript가 호출보다 페이지 아래에 더 정의 된 함수를 호출 할 때 불평합니다. 그러나 내 페이지는 게임용이며 전체 다운로드가 완료 될 때까지 함수가 호출되지 않습니다. 그렇다면 주문 함수가 내 코드에 나타나는 이유는 무엇입니까?

편집 : 답을 찾은 것 같습니다.

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

나는 안에서 신음하고있다. 6 천 줄의 코드를 다시 주문하는 데 다른 하루를 보내야하는 것 같습니다. 자바 스크립트의 학습 곡선은 전혀 가파르지는 않지만 매우 길다.


tl; dr 모든 것이로드 될 때까지 아무것도 호출하지 않으면 괜찮습니다.


편집 : 일부 ES6 선언 ( let, const)을 다루는 개요 : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_Cheatsheet

이 이상한 행동은

  1. 기능을 정의하는 방법 및
  2. 당신이 그들을 부를 때.

다음은 몇 가지 예입니다.

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();

이것은 호이 스팅 이라고 불리는 것 때문입니다 !

함수를 정의하는 방법에는 함수 선언 과 함수 표현식의 두 가지가 있습니다 . 차이점은 성가신, 분, 그래서 그냥이 약간 잘못된 말을하자 : 당신처럼 작성하는 경우 function name() {}, 그것은의 선언 , 그리고 당신처럼 쓸 때 var name = function() {}(또는 반환에 할당 된 익명 함수, 그런 일이), 그것의 함수 표현식 .

먼저 변수가 처리되는 방법을 살펴 보겠습니다.

var foo = 42;

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

이제 함수 선언 이 처리되는 방법 :

var foo = 42;
function bar() {}

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

var진술은 생성foo맨 위에 "던져" 지만 아직 가치를 할당하지는 않습니다. 함수 선언이 다음 줄에 나오고 마지막으로 값이에 할당됩니다 foo.

그리고 이것은 어떻습니까?

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

선언foo상단으로 이동합니다. 할당은 bar모든 호이 스팅이 발생하기 전인 호출 이 이루어진 후에 만 이루어집니다.

그리고 마지막으로 간결함을 위해 :

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

이제 함수 표현식은 어떻습니까?

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

Just like regular variables, first foo is declared at the highest point of the scope, then it is assigned a value.

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

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

As we've seen before, only the creating of foo is hoisted, the assignment comes where it appeared in the "original" (un-hoisted) code. When bar is called, it is before foo is assigned a value, so foo === undefined. Now in the function-body of bar, it's as if you're doing undefined(), which throws an error.


The main reason is probably that JSLint does only one pass on the file so it doesn't know you will define such a function.

If you used functions statement syntax

function foo(){ ... }

There is actually no difference at all where you declare the function (it always behaves as if the declaration is on the beginning).

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

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

You have to guarantee you wont call it before the initialization (this can actually be a source of bugs).


Since reordering tons of code is complicated and can be a source of bugs in itself, I would suggest you search for a workaround. I'm pretty sure you can tell JSLint the name of global variables beforehand so it doesn't complain about undeclared stuff.

Put a comment on the beggining of the file

/*globals foo1 foo2 foo3*/

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


There are way too many people pushing arbitrary rules about how JavaScript should be written. Most rules are utter rubbish.

Function hoisting is a feature in JavaScript because it is a good idea.

When you have an internal function which is often the utility of inner functions, adding it to the beginning of the outer function is an acceptable style of writing code, but it does have the drawback that you have to read through the details to get to what the outer function does.

You should stick to one principle throughout your codebase either put private functions first or last in your module or function. JSHint is good for enforcing consistency, but you should ABSOLUTELY adjust the .jshintrc to fit your needs, NOT adjust your source code to other peoples wacky coding concepts.

One coding style that you might see in the wild you should avoid because it gives you no advantages and only possible refactoring pain:

function bigProcess() {
    var step1,step2;
    step1();
    step2();

    step1 = function() {...};
    step2 = function() {...};
}

This is exactly what function hoisting is there to avoid. Just learn the language and exploit its strengths.


Only function declaration are hoisted not function expression (assignment).

참고URL : https://stackoverflow.com/questions/7609276/javascript-function-order-why-does-it-matter

반응형