>  기사  >  웹 프론트엔드  >  자바스크립트 실행순서 상세 소개_기본지식

자바스크립트 실행순서 상세 소개_기본지식

WBOY
WBOY원래의
2016-05-16 17:10:501418검색

이전에는 JavaScript 엔진의 구문 분석 메커니즘을 통해 JavaScript의 작동 원리를 살펴보았습니다. 아래에서는 페이지에서 JavaScript 코드의 실행 순서를 설명하기 위해 보다 생생한 예를 사용합니다. JavaScript 엔진의 작동 메커니즘이 기본 동작에 속하기 때문에 상대적으로 심오하다면 JavaScript 코드의 실행 순서는 더 생생합니다. 물론 JavaScript 코드의 실행 순서를 직관적으로 느낄 수 있기 때문입니다. 상대적으로 복잡하기 때문에 JavaScript 언어를 살펴보기 전에 프로파일링하는 것도 필요합니다.
1.1 HTML 문서 흐름 순서대로 자바스크립트 코드 실행
우선 브라우저에서 HTML 문서를 파싱하는 과정은 다음과 같다는 점을 독자들은 알아야 한다. 브라우저는 문서 흐름을 따른다. 위에서 아래로 아래는 페이지 구조와 정보를 단계별로 분석한 것입니다. 내장된 스크립트인 JavaScript 코드도 HTML 문서의 구성 요소로 간주되므로 로드 중 JavaScript 코드의 실행 순서도 스크립트 태그 <script>가 나타나는 순서에 따라 결정됩니다. 예를 들어 아래 문서 페이지를 탐색하면 코드가 위에서 아래로 단계별로 구문 분석되는 것을 볼 수 있습니다. </p> <p></p> <div class="codetitle"> <span><a style="CURSOR: pointer" data="48269" class="copybut" id="copybut48269" onclick="doCopy('code48269')"><u>코드 복사</u></a></span> 코드는 다음과 같습니다.</div> <div class="codebody" id="code48269"> <br><script><br>alert( "상위 스크립트");<br></script>
<script>alert("head script");<BR></script&gt ;<BR><title></title><BR></head><BR><body><BR><script><BR>alert("페이지 스크립트");<BR>&lt ;/ script><BR></body></html><BR><script><BR>alert("하단 스크립트");<BR></script>

스크립트 태그 <script>의 src 속성을 통해 외부 JavaScript 파일 스크립트를 가져오는 경우 해당 명령문이 나타나는 순서대로 실행되며 실행 프로세스는 문서 로딩의 일부입니다. 외부 JavaScript 파일이므로 실행이 지연되지 않습니다. 예를 들어 위 문서의 헤드와 본문 영역에 있는 스크립트를 외부 자바스크립트 파일로 옮긴 후 src 속성을 통해 가져옵니다. 계속해서 페이지 문서를 미리 보면 동일한 실행 순서를 볼 수 있습니다. <br></p> <div class="codetitle"> <span><a style="CURSOR: pointer" data="39983" class="copybut" id="copybut39983" onclick="doCopy('code39983')"><u>코드 복사</u></a></span> 코드는 다음과 같습니다.</div> <div class="codebody" id="code39983"> <br><script> <p>alert("상위 스크립트");</p> <p></script>

<제목>

<본문>

<스크립트>

alert("하단 스크립트");

1.2 사전 컴파일과 실행 순서의 관계

Javascript에서 함수는 Javascript의 첫 번째 유형입니다. 함수를 작성할 때 실제로는 함수 유형의 엔터티를 만드는 것입니다.
다음과 같은 형식으로 작성할 수 있습니다.

코드를 복사합니다. 코드는 다음과 같습니다.

functionHello()
{
alert("안녕하세요")
}
Hello()
varHello = function()
{
alert( "Hello") ;
}
Hello();

사실 다 똑같습니다. 하지만 함수를 수정하면 매우 이상한 문제를 발견하게 됩니다.
코드 복사 코드는 다음과 같습니다.

  ​ 
functionHello() {                                                                🎜>
< /스크립트>


다음과 같은 결과를 볼 수 있습니다. Hello World가 두 번 연속으로 출력됩니다.
우리가 상상했던 Hello, Hello World가 아닙니다.
Javascript는 완전히 순차적으로 해석되어 실행되지는 않지만, Javascript는 해석되기 전에 "사전 컴파일"되어 있기 때문입니다. 사전 컴파일 과정에서는 정의된 함수가 먼저 실행되고, var 변수가 먼저 실행됩니다. 프로그램의 실행 효율성을 높이기 위해 생성되었으며 기본값은 정의되지 않았습니다.
즉, 위의 코드 조각은 실제로 JS 엔진에 의해 다음 형식으로 사전 컴파일됩니다.
코드 복사 코드는 다음과 같습니다.

                                                              ) {
                                                                                                                                           위의 코드를 보면 함수도 데이터이자 변수라는 점을 분명히 알 수 있습니다. . "기능"에 값을 할당(재할당)할 수도 있습니다.
물론 이러한 상황을 방지하기 위해 다음과 같이 할 수도 있습니다.




코드 복사


코드는 다음과 같습니다. 다음 :


ScriptType = " Alert (Hello");
functionHello() {
alert("Hello World") } Hello() 이런 식으로 프로그램이 두 부분으로 나뉘는데, JS 엔진에서는 이를 하나로 묶지 않습니다. 
JavaScript 엔진은 스크립트를 구문 분석할 때 사전 컴파일 중에 선언된 모든 변수와 함수를 처리합니다.

다음을 수행하세요.

1. 실행 전에 "사전 컴파일"과 유사한 작업이 수행됩니다. 먼저 현재 실행 환경에서 활성 개체가 생성되고 var로 선언된 변수가 활성 개체의 속성으로 설정되지만, 이번에는 이러한 변수 할당 값이 모두 정의되지 않았으며 함수로 정의된 함수도 활성 개체의 속성으로 추가되며 해당 값은 정확히 함수의 정의입니다.

2. 해석 및 실행 단계에서 변수를 구문 분석해야 할 경우 현재 실행 환경의 활성 개체에서 해당 변수를 먼저 검색하고 실행 환경 소유자가 프로토타입을 가지고 있습니다. 속성인 경우 프로토타입 체인에서 검색되고, 그렇지 않으면 범위 체인에 따라 검색됩니다. var a = ...와 같은 문을 만나면 해당 변수에 값이 할당됩니다(참고: 변수 할당은 해석 및 실행 단계에서 완료됩니다. 이 전에 변수를 사용하면 해당 값이 정의되지 않음) 따라서 JavaScript 인터프리터가 다음 스크립트를 실행할 때 오류가 보고되지 않는 것으로 나타납니다.





코드 복사

코드는 다음과 같습니다.

alert(a) >

var a =1;

alert(a);                                                                            // 반환 값 1
변수 선언은 사전 컴파일 중에 처리되므로 실행 중에 모든 코드에 표시됩니다. 그러나 위 코드를 실행하면 프롬프트된 값이 1이 아니라 정의되지 않은 것을 볼 수 있습니다. 이는 변수 초기화 과정이 사전 컴파일이 아닌 실행 중에 발생하기 때문입니다. 실행 중에 JavaScript 인터프리터는 코드를 순서대로 구문 분석합니다. 이전 코드 줄에서 변수에 값이 할당되지 않으면 JavaScript 인터프리터는 기본값인 정의되지 않음을 사용합니다. 두 번째 줄에서는 변수 a에 값이 할당되므로 코드의 세 번째 줄에서는 변수 a의 값이 정의되지 않은 것이 아니라 1이라는 메시지가 표시됩니다.

마찬가지로 다음 예에서는 함수가 선언되기 전에 함수를 호출하는 것이 적법하고 올바르게 구문 분석할 수 있으므로 반환 값은 1입니다.

코드 복사 코드는 다음과 같습니다.

f()

함수 f(){

경고(1);

}

그러나 함수가 다음과 같이 정의되면 JavaScript 인터프리터는 구문 오류를 표시합니다.

코드 복사 코드는 다음과 같습니다.

f()

var f = 함수(){

경고(1);

}

위 예제에서 정의한 함수는 변수 f에만 값으로 할당되기 때문에 사전 컴파일 기간 동안 JavaScript 인터프리터는 변수 f의 선언과 변수 f의 값만 처리할 수 있습니다. 실행될 때까지만 기다릴 수 있습니다. 할당을 순차적으로 수행하면 자연스럽게 구문 오류가 발생하여 객체 f를 찾을 수 없다는 메시지가 나타납니다.

몇 가지 예를 살펴보세요.

코드 복사 코드는 다음과 같습니다.

코드 복사 코드는 다음과 같습니다.


변수와 함수 선언은 문서 어디에나 있을 수 있지만 모든 JavaScript 코드보다 먼저 전역 변수와 함수를 선언하고 변수를 초기화하고 할당하는 것이 좋습니다. 함수 내에서 변수는 먼저 선언된 다음 참조됩니다.

1.3 블록 단위로 JavaScript 코드 실행

소위 코드 블록은 <script> 태그로 구분된 코드 세그먼트입니다. 예를 들어, 아래 두 개의 <script> 태그는 두 개의 JavaScript 코드 블록을 나타냅니다. <p> </p> <p></p> <div class="codetitle"><span><a style="CURSOR: pointer" data="83113" class="copybut" id="copybut83113" onclick="doCopy('code83113')">코드 복사<u></u></a> 코드는 다음과 같습니다.</span></div> <div class="codebody" id="code83113"><script><br> // 자바스크립트 코드 블록 1<p> </p>var a =1;<p> </p></script>

<스크립트>

// 자바스크립트 코드 블록 2

함수 f(){

경고(1);

}

JavaScript 인터프리터는 스크립트를 실행할 때 블록 단위로 실행합니다. 평신도의 관점에서 보면 브라우저가 HTML 문서 스트림을 구문 분석할 때 <script> 태그를 발견하면 JavaScript 인터프리터는 코드 블록이 로드될 때까지 기다렸다가 코드 블록을 사전 컴파일한 다음 실행합니다. 실행 후 브라우저는 아래 HTML 문서 스트림을 계속 구문 분석하고 JavaScript 인터프리터는 다음 코드 블록을 처리할 준비가 됩니다. </p> <p>자바스크립트는 블록 단위로 실행되기 때문에 자바스크립트 블록 내에서 다음 블록에 선언된 변수나 함수를 호출하면 구문 오류가 발생합니다. 예를 들어 JavaScript 인터프리터가 다음 코드를 실행하면 변수 a가 정의되지 않았고 객체 f를 찾을 수 없다는 구문 오류가 표시됩니다. </p> <p></p> <div class="codetitle"> <span><a style="CURSOR: pointer" data="35451" class="copybut" id="copybut35451" onclick="doCopy('code35451')"><u>코드 복사</u></a></span> 코드는 다음과 같습니다.</div> <div class="codebody" id="code35451"> <br><script> <p>// 자바스크립트 코드 블록 1</p> <p>경고(a);</p> <p>에프();</p> <p></script>

<스크립트>

// 자바스크립트 코드 블록 2

var a =1;

함수 f(){

경고(1);

}


자바스크립트는 블록 단위로 실행되지만 서로 다른 블록은 동일한 전역 범위에 속하므로 블록 간 변수와 함수를 공유할 수 있습니다.

1.4 이벤트 메커니즘을 사용하여 JavaScript 실행 순서 변경

JavaScript는 코드를 블록 단위로 처리하고 HTML 문서 흐름의 구문 분석 순서를 따르기 때문에 위 예에서 이러한 구문 오류를 볼 수 있습니다. 그러나 문서 스트림을 로드한 후 다시 액세스하면 이러한 오류가 발생하지 않습니다. 예를 들어, 두 번째 코드 블록의 변수 및 함수에 접근하는 코드를 페이지 초기화 이벤트 함수에 배치하면 구문 오류가 발생하지 않습니다.

코드 복사 코드는 다음과 같습니다.

<script> <p>// 자바스크립트 코드 블록 1</p> <p>window.onload = function(){ // 페이지 초기화 이벤트 핸들러 함수</p> <p> 경고(a);</p> <p> f();</p> <p>}</p> <p></script>

<스크립트>

// 자바스크립트 코드 블록 2

var a =1;

함수 f(){

경고(1);

}


보안상의 이유로 일반적으로 페이지가 초기화된 후에만 JavaScript 코드 실행을 허용합니다. 이를 통해 JavaScript 실행에 대한 네트워크 속도의 영향을 피할 수 있으며 HTML 문서 흐름으로 인한 JavaScript 실행 제한도 피할 수 있습니다.

주목

페이지에 여러 windows.onload 이벤트 핸들러가 있는 경우 마지막 핸들러만 유효합니다. 이 문제를 해결하려면 모든 스크립트 또는 호출 함수를 동일한 onload 이벤트 핸들러에 넣을 수 있습니다.

코드 복사 코드는 다음과 같습니다.

window.onload = function(){

f1();

f2();

f3();

}

이런 식으로 onload 이벤트 핸들러에서 함수 호출 순서만 조정하면 함수 실행 순서를 변경할 수 있습니다.

페이지 초기화 이벤트 외에도 마우스 이벤트, 키보드 이벤트, 시계 트리거 등 다양한 대화형 이벤트를 통해 JavaScript 코드의 실행 순서를 변경할 수도 있습니다. 자세한 설명은 14장을 참조하세요.

1.5 JavaScript 출력 스크립트 실행 순서

JavaScript 개발에서는 문서 객체의 write() 메서드를 사용하여 JavaScript 스크립트를 출력하는 경우가 많습니다. 그렇다면 이러한 동적 출력 스크립트는 어떻게 실행됩니까? 예:

코드 복사 코드는 다음과 같습니다.

document.write('');


위 코드를 실행하면 document.write() 메서드가 먼저 스크립트가 있는 문서 위치에 출력 스크립트 문자열을 쓰고, 브라우저는 문서의 내용을 구문 분석한 후 계속 구문 분석합니다. document.write()가 위치합니다. 그러면 document.write()에 의해 출력된 콘텐츠가 구문 분석되어 다음 HTML 문서를 구문 분석합니다. 즉, JavaScript 스크립트에 의해 출력된 코드 문자열은 출력 직후에 실행됩니다.

document.write() 메소드를 사용한 JavaScript 스크립트 문자열 출력은 역시 출력되는 <script> 태그에 배치되어야 합니다. 그렇지 않으면 JavaScript 해석기가 이러한 합법적인 JavaScript 코드를 인식하지 못하고 일반 코드로 처리합니다. 문자열이 페이지 문서에 표시됩니다. 예를 들어 다음 코드는 JavaScript 코드를 실행하는 대신 표시합니다. </p> <p></p> <div class="codetitle"> <span><a style="CURSOR: pointer" data="94458" class="copybut" id="copybut94458" onclick="doCopy('code94458')"><u>코드 복사</u></a></span> 코드는 다음과 같습니다.</div> <div class="codebody" id="code94458"> <br>document.write('f(); '); <p>document.write('function f(){');</p> <p>document.write('alert(1);');</p> <p>document.write(');');<br></p> </div> <p>그러나 document.write() 메서드를 통해 스크립트를 출력하고 실행하는 데에는 특정 위험이 있습니다. 왜냐하면 서로 다른 JavaScript 엔진이 서로 다른 순서로 스크립트를 실행하고, 브라우저마다 구문 분석에 버그가 있을 수 있기 때문입니다. </p> <p>Ø 문제 1: document.write() 메서드를 통해 가져온 외부 JavaScript 파일에 선언된 변수 또는 함수를 찾을 수 없습니다. 예를 들어 아래 샘플 코드를 살펴보세요. </p> <p></p> <div class="codetitle"> <span><a style="CURSOR: pointer" data="27974" class="copybut" id="copybut27974" onclick="doCopy('code27974')"><u>코드 복사</u></a></span> 코드는 다음과 같습니다.</div> <div class="codebody" id="code27974"> <br>document.write('<script type ="text /javascript" src="http://www.jb51.net/test.js"> <p></script>');

document.write('');

Alert (n 1); // 모든 브라우저는 변수가 변수 n을 찾을 수 없다는 메시지를 표시합니다.

외부 JavaScript 파일(test.js)의 코드는 다음과 같습니다.

코드를 복사하세요 코드는 다음과 같습니다. 다음은 다음과 같습니다.

var n = 1;

다른 브라우저에서 테스트하면 구문 오류가 발생하고 변수 n을 찾을 수 없습니다. 즉, JavaScript 코드 블록에서 이 코드 블록의 document.write() 메서드를 사용하여 스크립트 출력에 가져온 외부 JavaScript 파일에 포함된 변수에 액세스하면 구문 오류가 표시됩니다. 동시에 IE 브라우저의 경우 스크립트뿐만 아니라 출력 스크립트에서도 외부 JavaScript 파일로 가져온 출력 변수를 찾을 수 없다는 메시지가 표시됩니다(표현이 약간 길고 복잡함). , 이해하지 못하는 독자는 위 코드를 실행해 보면 이해할 수 있습니다.)

Ø 질문 2: JavaScript 엔진마다 외부 가져오기 스크립트 출력에 대한 실행 순서가 약간 다릅니다. 예를 들어 아래 샘플 코드를 살펴보세요.

코드 복사 코드는 다음과 같습니다.

');

document.write('');



외부 자바스크립트 파일(test1.js)에 대한 코드는 다음과 같습니다.
코드 복사 코드는 다음과 같습니다.

var n = 1;

경고(n);

IE 브라우저에서의 실행 순서는 그림 1-6과 같습니다.

자바스크립트 실행순서 상세 소개_기본지식

그림 1-6 IE 7 브라우저 실행 순서 및 프롬프트된 구문 오류

DOM 표준을 준수하는 브라우저의 실행 순서는 IE 브라우저와 다르며, 구문 오류는 없습니다. 그림 1-7은 Firefox 3.0 브라우저의 실행 순서를 보여줍니다.

자바스크립트 실행순서 상세 소개_기본지식

그림 1-7 Firefox 3 브라우저 실행 순서 및 프롬프트된 구문 오류

브라우저마다 다른 실행 순서와 발생 가능한 버그를 해결하세요. 출력 스크립트를 사용하여 가져온 모든 외부 파일을 독립적인 코드 블록에 넣을 수 있으므로 위에서 소개한 JavaScript 코드 블록의 실행 순서에 따라 이러한 문제를 피할 수 있습니다. 예를 들어 위의 예에서는 다음과 같이 디자인할 수 있습니다.

코드 복사 코드는 다음과 같습니다.

');

');

alert(n 3) // 팁 4

이렇게 하면 위의 코드는 다양한 브라우저에서 순서대로 실행될 수 있으며, 출력 순서는 1, 2, 3, 4, 5가 됩니다. 문제의 원인은 가져온 스크립트 출력과 현재 JavaScript 코드 블록 간의 모순입니다. 별도로 출력하면 충돌이 발생하지 않습니다.

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
이전 기사:JavaScript에서 비공개 속성을 사용하여 클래스를 작성하는 방법 (1)_javascript 기술다음 기사:JavaScript에서 비공개 속성을 사용하여 클래스를 작성하는 방법 (1)_javascript 기술

관련 기사

더보기