시간이 어떻게 될지 모르겠지만 앞으로 계속 쭉~~~~ 강좌(?)를 쓸예정이다.
참고로 혼자 떠드는 스타일이라 존칭어는 과감하게 생략토록 하겠다.ㅋㅋ
강좌라고 하기엔 좀 납득하기 어려운 부분도 있겠지만 글머리를 봐주길 바란다.
그렇다! 기초강좌다 -_-;
기초강좌의 주된 목적은 초보 또는 아직 Javascript에 대한 개념이 정립되지 않은 상태에서
이것저것 하다보니 헛깔리는 분들을 위한것이 주가 되겠다.
오늘은 첫날이므로 조금은 쉽지만 자주 헛깔릴 수 있는 것을 다뤄보겠다.
이름하여 Javascript의 Runtime이다.
말그대로 "Runtime"... (실행시간이 아니다 --;) 실행할때의 시점으로 봐주길 바란다.
주절주절 떠드는 것보다 아래의 코드를 보며 접해보는게 좋겠다 ^^*
<html>
<script>
function test_1(){ alert("test_1"); }
function test_2(){ alert("test_2"); }
function test_3(){ alert("test_3"); }
test_1();
</script>
<body onload="test_2()">
<script>test_3()</script>
</body>
</html>
위 소스는 그리 어렵지 않다. 아니다 하나도 안어렵다. 만약 이것이 어렵다고
느끼시는 분이 있다면.... 대.략.난.감. !!
자, 해설을 해보자. 여러분들은 위의 실행순서가 어떻게 될지 예상이 되는가?
여기서 두그룹으로 나눠볼 수 있겠다.
1번째 그룹은 아마 test_1 -> test_2 -> test_3 으로 예상할 것이고,
2번째 그룹은 아마 test_1 -> test_3 -> test_2 으로 예상할 것이다.
혹시, 이 두그룹에 속하지 않는 당신이라면... 역시... 대.략.난.감 !!
직접 실행해보면 알겠지만 답은 2번째 그룹이 정답이다. 왜 이런 일이 발생할까?
쉽게 생각하면 1번째 그룹이 답이 될 수도 있다. 왜? 음.. 이제부터 그룹1을 대표해서
설명을 해주겠다 (물론 틀린해석이지만 ^^.. 가능성을 이야기해주고 싶은것이다)
test_1은 당연 먼저실행된다. 왜냐면 Javascript는 인터프리터 언어이기때문에
위에서 아래로 순차적으로 해석되어지면서 실행이 된다. 그래서 test_1이 가장먼저
실행이된다. 그리고 자주보던 onLoad 문이다..그렇다 우리는 잘배웠다!! onLoad는
body가 전부 로드되면(여기에 함정이 있다) 실행되는 것이다. 그래서 test_2가 실행되고,
body 안에 있는 test_3가 실행된다고 생각된 것이다. (사실 나도 첨엔 그리 생각했다^^;)
하지만 위에도 말했듯이 위에 말은 사실이 아니다. 더 정확하게 말하면 오해이다.
자! 그럼 사실대로 오해없이 이해해보자.
위의 잘못된 설명중 초반엔 맞는 설명이다. 어디까지냐면, onLoad전까지 이다. 그다음엔
body의 onLoad를 자세히 이해할 필요가 있다. body는 무엇인가? 그렇다. 단순한 몸뚱이가 아니다 ^^
body는 html의 몸뚱이이며 DOM객체의 일부이다. onLoad는 body, 더 정확하게는 DOM의 일부인
body가 전부 로드되었을때 실행이 되는 것이다. 그런데 왜 test_3가 먼저실행되었냐?
그건 위에 설명된 인터프리터 언어의 특성때문에 위에서 순차적으로 읽어내려가면서 실행이
되기 때문이다. 쉽게 DOM은 DOM이고 JS는 JS인것이다. 아주~ 나중에~ 다시 언급되겠지만
DOM의 참조를 JS에 넘기면 IE에서 memory leak이 발생한다. 잠시 어려운 이야기를 했는데
나중되면 다 이해하리라... 다시 본론으로 쿨럭! -_-;
body안에 스크립트가 있긴하지만 DOM의 일부가 아니기에 인터프리터의 특성으로 먼저실행되어지고,
그다음에 body onLoad가 실행되어지는 것이다. 이해하셨는가? 힘들게 설명했는데, 이해못하면 안된다 ㅠㅠ OTL
자 여기까지 이해했다면, 난이도를 조금 높여보자.
<html>
<script>
test_2();
function test_5(){
this.msg = "hello~ test_5";
this.call = function(){
alert(this.msg);
}
test_4();
this.call();
}
function test_1(){ alert("test_1"); }
function test_2(){ alert("test_2"); }
function test_3(){ alert("test_3"); }
function test_4(){ alert("test_4"); }
</script>
<body onload="test_1()">
<script>
new test_5();
test_3();
</script>
</body>
</html>
문제는 동일하다. 실행순서 실행결과를 맞추면 된다. 어려워 보이는가? 절대 그렇지 않다.
결론부터 말하자면 test_2 -> test_4 -> test_5 -> test_3 -> test_1 순이다.
이해가는 사람도 있을것이고, 아직 잘 이해가 안되는 사람도 있을 것이다. 어쩔수 없다.
이해가 안되면 되게해야 인지상종의 정신이 아니던가??
해설 들어간다.
Javascript는 인터프리터이며, 순차적으로 실행한다 했다. 근데!!!! 이게 왠말인가?
함수를 정의하기도 전에 호출을 해버린게 아닌가? 이게 말이되는건가? 결론적으로 말이된다.
Javascript는 인터프리터이므로 순차적이다. 그러나 순차적이 한줄한줄 순처적이기도 하지만, <script></script> 안에서는 한줄한줄이나, <script></script>로 봤을땐 한통속인것이다.
즉, test_2()를 먼저 호출했지만 Javascript엔진이 <script></script>한 구문을 해석하는 시간이
test_2()를 호출하는 시간하고 크게 차이 안났다는 이야기다. 아니 더 정확하게 말하자면 거의 동시에
이루어졌다고 봐야한다.
더 적나라하게 말하면 <script></script>사이에 어디에서라도 수가 정의되기전에 함수를 호출해도 동일한
태그안에서 함수가 정의만 되어있으면 호출이 된다는 이야기이다.(안될 경우있음)
어떤가? 말도 안되는 일이지 않는가? 아무리 빠르다고 해도 이게 말이되는건가? 그렇다
Javascript는 원래 말이 안되는 언어이다.. 완벽한 oop도 아니면서 oop에 가깝다.
코딩의 자율성도 상당히 높아서 잘못된(Java또는 그외 언어와 비교하여) 코딩도 맘넓게 이해해주는
센스도 있다.
여기서 잠깐! 위에 보면 test_5()를 보시라.. 좀 특이하게 생겨먹었다.
Javascript에서 "like class"(oop에서의 class와 비교하여)를 생성하는 방법중에 하나이다.
자세한건 뒤에 다루기로 한다. 여기서는 그냥 이런것도 있구나, 이렇게 쓸수 있구나하는 정도까지만
이해해 두자.
근데, 아무리 성격이 좋은 Javascript라도 안되는게 있다.
<html>
<script> test_2(); </script>
<body>
</body>
<script>
function test_2(){ alert("test_2"); }
</script>
</html>
위 스크립트를 실행하면 어떤 결과가 나올지 예상이 되는가? 그렇다.. 에러다 -_-;;
왜 그러한가? 설명은 위에 있다. Javascript에서 엔진이 해석하는 순서는 <script></script> 단위이고,
그안에서는 대부분 자유롭게 기술할 수 있다.(안되는 경우가 있다. 언제냐고? 스스로 생각해보자 ^^)
허나 위의 구문은 하나의 <script></script>에서는 정의되지 않은 함수를 호출하고,
아래의 다른 <script></script>에서는 함수를 정의했다. 그래서 안되는거다.
Javascript의 엔진이 해석하는 단위에서 정의와 호출이 따로 있기 때문이다.
이상 Javascript 에서의 런타임에 대해서 간략하게나마 정리해 보았다.
간혹 이해가 안가시는 분이나, 도통 모르겠다고 생각되시는 분들은 차근차근 다시 위 글을 읽어 보시기
바란다. 위 내용은 어느 책에도 나와있지 않기때문에 오로지 경험에 의해서만 알 수 있는 것이다.
쉽게 "노하우"란 이야기이다. 다들 열심히 공부하여 앞으로 나올 Javascript 2.0시대에
조금이라도 쉽게 다가갈 수 있도록 화이팅이다.
posted by blankus
이 글의 트랙백 주소 :: http://www.blankus.net/trackback/2