원래 질문 :
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
이 이상한 행동은
- 기능을 정의하는 방법 및
- 당신이 그들을 부를 때.
다음은 몇 가지 예입니다.
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();
그냥 일반 변수처럼, 처음 foo
됩니다 선언 다음에 값이 할당되고, 범위의 가장 높은 지점에서.
두 번째 예제에서 오류가 발생하는 이유를 살펴 보겠습니다.
bar();
function bar() {
foo();
}
var foo = function() {}
//=>
var foo;
function bar() {
foo();
}
bar();
foo = function() {}
이전에 보았던 것처럼 생성 만 foo
게양되고 할당은 “원본”(게재되지 않은) 코드에 나타난 위치에 제공됩니다. bar
를 호출 하면 이전 foo
에 값이 할당되므로 foo === undefined
. 이제의 함수 본문에서 bar
마치 수행하는 것처럼 undefined()
오류가 발생합니다.
답변
주된 이유는 아마도 JSLint가 파일에 대해 하나의 패스 만 수행하므로 이러한 함수를 정의 할 것인지 알지 못하기 때문일 것입니다 .
함수 문 구문을 사용한 경우
function foo(){ ... }
실제로 함수를 선언하는 위치에는 차이가 없습니다 (항상 선언이 시작 부분에있는 것처럼 동작 함).
반면에 함수가 일반 변수처럼 설정된 경우
var foo = function() { ... };
초기화 전에 호출하지 않도록 보장해야합니다 (실제로 버그의 원인이 될 수 있음).
수많은 코드를 재정렬하는 것은 복잡하고 그 자체로 버그의 원인이 될 수 있으므로 해결 방법을 검색하는 것이 좋습니다. 선언되지 않은 항목에 대해 불평하지 않도록 JSLint에게 전역 변수의 이름을 미리 알려줄 수 있다고 확신합니다.
파일 시작에 대한 주석을 달아주세요.
/*globals foo1 foo2 foo3*/
또는 거기에 텍스트 상자를 사용할 수 있습니다. (저는 또한 당신이 그것에 간섭 할 수 있다면 당신이 내부 jslint 함수에 대한 인수에 이것을 전달할 수 있다고 생각합니다.)
답변
JavaScript 작성 방법에 대한 임의의 규칙을 추진하는 사람들이 너무 많습니다. 대부분의 규칙은 완전히 쓰레기입니다.
함수 호이 스팅은 좋은 아이디어이기 때문에 JavaScript의 기능입니다.
내부 함수의 유틸리티 인 내부 함수가있을 때 외부 함수의 시작 부분에 추가하는 것은 코드 작성에 허용되는 스타일이지만 세부 정보를 읽어야하는 단점이 있습니다. 외부 기능이 수행합니다.
코드베이스 전체에서 하나의 원칙을 고수해야합니다. 전용 함수를 모듈이나 함수에서 맨 처음 또는 마지막에 두십시오. JSHint는 일관성을 강화하는 데 유용하지만 다른 사람들의 엉뚱한 코딩 개념에 맞게 소스 코드를 조정하지 말고 필요에 맞게 .jshintrc를 절대적으로 조정해야합니다.
야생에서 볼 수있는 한 가지 코딩 스타일은 이점이없고 가능한 리팩토링 고통 만 제공하므로 피해야합니다.
function bigProcess() {
var step1,step2;
step1();
step2();
step1 = function() {...};
step2 = function() {...};
}
이것이 바로 피해야 할 기능 호이 스팅입니다. 언어를 배우고 그 강점을 활용하십시오.
답변
함수 표현 (할당)이 아닌 함수 선언 만 게양됩니다.