--- title: JavaScript가 뭔가요? slug: Learn/JavaScript/First_steps/What_is_JavaScript tags: - Article - Beginner - CodingScripting - Guide - JavaScript - Learn - Script translation_of: Learn/JavaScript/First_steps/What_is_JavaScript ---
MDN의 JavaScript 초급자 과정에 오신 걸 환영합니다! 이 글은 JavaScript를 넓게 보면서 "뭔가요?", "뭘 하나요?"와 같은 질문을 답변하고, 여러분이 JavaScript에 친숙해지도록 도와드립니다.
전제 조건: |
기본적인 컴퓨터 능력, HTML과 CSS 기초. |
---|---|
목표: | JavaScript가 뭔지, 어떤 일을 할 수 있는 지, 웹사이트에 어떻게 적용하는지 알기. |
자바스크립트는 복잡한 무언가(주기적으로 내용이 갱신되는 기능이나 능동적인 지도, 변화하는 2D/3D 그래픽, 동영상 등)를 웹페이지에 적용할 수 있게 하는 스크립트 혹은 프로그래밍 언어입입니다. 자바스크립트는 표준 웹 기술이라는 레이어 케이크에서 세번째 층이라고 볼 수 있습니다. 다른 두 층(HTML과 CSS)에 대한 보다 자세한 정보는 학습 영역의 다른 부분에서 찾아 볼 수 있습니다.
3개의 요소들은 각각 유기적으로 잘 구성되어 있습니다. 예제와 같이 간단한 폼을 만들어 봅시다. HTML을 사용하여 그 구조와 목적에 맞게 마크업 할 수 있습니다:
<p>Player 1: Chris</p>
그리고 CSS를 추가하여 이쁘게 꾸밀 수도 있습니다:
p { font-family: 'helvetica neue', helvetica, sans-serif; letter-spacing: 1px; text-transform: uppercase; text-align: center; border: 2px solid rgba(0,0,200,0.6); background: rgba(0,0,200,0.3); color: rgba(0,0,200,0.6); box-shadow: 1px 1px 2px rgba(0,0,200,0.4); border-radius: 10px; padding: 3px 10px; display: inline-block; cursor:pointer; }
그러고 마지막으로 약간의 자바스크립트로 동적인 기능을 추가할 수 있습니다:
const para = document.querySelector('p'); para.addEventListener('click', updateName); function updateName() { let name = prompt('Enter a new name'); para.textContent = 'Player 1: ' + name; }
{{ EmbedLiveSample('A_high-level_definition', '100%', 80, "", "", "hide-codepen-jsfiddle") }}
마지막 버전의 텍스트 라벨을 클릭하여 어떻게 되는 지 확인해봅시다. (이 데모는 Github에서도 볼 수 있습니다. source code 나 run it live를 참고해보세요!)
자바스크립트는 보다 더 많은 일들을 할 수 있습니다. 이제 더 자세한 내용을 살펴봅시다!
자바스크립트 언어의 핵심은 다음과 같은 일들을 할 수 있게하는 프로그래밍 기능들로 구성되어 있습니다:
name
이라는 변수에 저장하였습니다.name
이라고 만든 변수와 겹합하여 "Player 1: Chris"라는 글을 완성할 수 있었습니다.하지만 더욱 흥미진진한 것은 코어 자바스크립트 언어(core JavaScript language) 기반의 기능성입니다. 소위 Application Programming Interfaces (APIs) 라는 것은 여러분의 자바스크립트 코드에 사용할 수 있는 추가적인 강력한 마법들을 제공합니다.
API는 이미 만들어진 코드의 집합체라고 볼 수 있으며, 개발자들이 만들기 어렵고 힘든 부분을 쉽게 구현하도록 하는 프로그램이라고 볼 수 있습니다. 마치 집에서 가구를 만들 때 직접 디자인하고, 재료를 구하고, 재단하고, 못을 박고 하는 등 혼자서 모든 것을 하는 대신 가구 만들기 키트를 사는 것과 같다고 보면 됩니다.
일반적으로 두 종류로 구분됩니다.
Browser API는 웹 브라우저에 설치된 API들로, 컴퓨터 환경구성으로 부터 데이터를 보이게 하고 복잡한 일들을 하게 합니다. 예를 들어:
Note: 대부분의 데모 코드들은 오래된 브라우저에서는 실행이 안될 수 있으니, FireFox, Chrome, Edge, Opera와 같은 최신의 브라우저를 사용하는 것을 추천합니다. 실제 배포가 되는 코드처럼 여러 사용자가 사용할 수 있음을 고려하여 cross browser testing(여러 브라우저를 이용하여 테스트)를 해보는 것이 좋습니다.
Third party API 는 브라우저에 기본적으로 설치된 API가 아닌 인터넷에서 개인적으로 정보와 코드를 얻어 프로그래밍한 것을 말합니다. 예를 들어:
Note: 이러한 API 들은 고급 과정이며, 이 과정에서는 다루지 않을 것입니다. 이 API들에 대한 보다 자세한 정보는 Client-side web APIs module에서 살펴보세요.
물론 이것말고도 엄청나게 다양한 API들이 존재합니다! 하지만, 이 수업을 듣고 Facebook, Google Maps, Instagram등을 만들 수는 없으니 흥분하지는 말길 바랍니다. 이것보다 우리는 먼저 기본적인 것에 대해 배울 것이고 이것이 곧 이 수업을 진행하는 목적입니다. 자 시작해봅시다!
여기서 몇가지 코드를 실제로 살펴보고, 페이지에서 자바스크립트가 언제 어떻게 작동하는지 알아 볼 것입니다.
브라우저에서 웹페이지를 불러올 때 어떤 일이 발생하는지 생각해봅시다(먼저 How CSS works를 읽어 보세요.). 브라우저에서 웹페이지를 불러올 때, 실행 환경(브라우저 탭)안에서 HTML, CSS, Javascript 코드가 실행됩니다. 이는 마치 공장에서 원재료(코드)가 일련의 과정을 거쳐 제품(웹페이지)으로 탄생되는 것과 같습니다.
자바스크립트는 HTML과 CSS가 결합되고 웹페이지 상에서 올려진 후, 브라우저의 자바스크립트 엔진에 의해 실행됩니다. 이는 페이지의 구조와 스타일등을 정해놓고, 자바스크립트가 실행된다는 것과 같은 의미입니다.
동적으로 사용자 인터페이스를 업데이트하는 자바스크립트의 사용은 Document Object Model API를 통해 HTML과 CSS를 수정하는 것으로 좋은 현상입니다. 만약 자바 스크립트가 HTML과 CSS 전에 실행되었다면 문제가 분명 발생할 것입니다.
각각의 브라우저 탭들은 코드가 실행되는 개별적인 구성(이러한 것은 "실행 환경"이라고 지칭한다)입니다. 이는 각 탭의 대부분의 경우는 완전히 독립적이고, 하나의 탭의 코드는 다른 탭이나 웹사이트에 직접적으로 영향을 줄 수 없다는 의미입니다 . 이는 보안성에 좋은 방법입니다. 만약 이러한 부분이 없다면, 해커들이 다른 웹사이트로 부터 정보를 가로채는 등 악랄한 짓들을 할 수 있습니다.
Note: 물론 코드나 정보를 동떨어진 웹사이트나 탭으로 전송할 수 있는 안전한 방식이 존재합니다. 하지만 지금 과정과는 거리가 멀기 때문에 여기서는 다루지 않도록 하겠습니다.
브라우저에서 자바스크립트를 만났을 때 일반적으로는 위에서 아래 순서대로 실행됩니다. 이는 순서에 주의해서 코드를 작성해야한다는 의미입니다. 예를 들어, 아래의 첫번째 예제를 통해 자바스크립트 블록을 반환해봅시다:
const para = document.querySelector('p'); //HTML 요소 중 p태그를 선택 para.addEventListener('click', updateName); //para에 저장된 객체가 클릭되었을 때 updateName 함수를 실행 function updateName() { let name = prompt('Enter a new name'); //'Enter a new name'과 입력란 출력하여 입력받은 값을 name에 저장 para.textContent = 'Player 1: ' + name; //papa(p태그)에 새로운 문자열 저장 }
먼저 p태그의 요소를 para변수에 저장합니다(1번줄). 그리고 event listener를 붙여(3번줄) p태그가 클릭되었을 때 updateName()
코드 블록(중괄호로 묶여있는 부분)이 (5-8번줄) 실행되도록 합니다. updateName()
코드 블록(이렇게 계속적으로 사용할 수 있는 코드 블럭을 함수라고 합니다.). 사용자로 하여금 새로운 이름을 입력받기를 요청하고, 사용자가 이름을 입력하면 화면에 출력하게 됩니다.
만약 1번줄과 3번줄을 바꿨다면 코드는 실행되지 않을 것입니다. 대신 브라우저의 개발자 콘솔창에 다음과 같은 에러 알림이 뜰 것입니다. — TypeError: para is undefined
. 이는 para라는 객체가 아직 존재하지 않는다는 뜻으로, para라는 변수에 event listener는 추가할 수 없습니다
Note: 이는 매우 일반적인 에러이기 때문에, 프로그램을 실행할 때 코드 상에서 사용되는 객체에 대해 주의할 필요가 있습니다.
프로그래밍을 하는 입장에서 인터프리트와 컴파일이라는 개념에 대해서는 들어보았을 것입니다. 자바스크립트는 해석형 언어입니다. 따라서 코드가 위에서 아래로 순차적으로 실행되고 그 즉시 결과가 반환됩니다. 브라우저에서 동작하기 전에 다른 방식으로 코드를 변환할 필요가 없습니다.
반면에 컴파일러형 언어는 컴퓨터에 의해 동작되기전 다른 형식으로 변환하는 언어입니다. 예를 들면 C/C++과 같은 언어는 어셈블리어로 컴파일되어 동작됩니다.
이 둘의 관점은 각각의 장점을 가지고 있으니 다음장 부터 한번 알아봅시다.
웹 개발 맥락에서 서버측과 클라이언트측 코드에 대해 들어보았을 것입니다. 클라이언트측 코드란 사용자의 컴퓨터에서 작동되는 코드입니다. 만약 웹페이지를 보고자 한다면, 클라이언트측 코드가 사용자의 컴퓨터로 다운로드되고 브라우저가 이를 표시합니다. 이러한 자바스크립트 모듈을 정확히는 클라이언트측 자바스크립트라고 합니다.
반면 서버측 코드는 서버에서 작동되고, 그 결과가 사용자의 브라우저에 넘어가 표시됩니다. PHP, Python, Ruby, ASP.NET등이 서버측 웹 언어의 대표적 예라고 볼 수 있습니다. 물론 자바스크립트도 가능합니다! 유명한 Node.js란 환경을 통해 서버측에서도 자바스크립트가 사용 가능합니다. Dynamic Websites – Server-side programming에서 서버측 자바스크립트에 대해 더 알 수 있습니다.
"동적"이라는 말은 클라이언트측 서버측 언어 모두를 가르킵니다. 이는 각기 다른 상황에서 적절한 정보가 보이고, 컨텐츠를 웹페이지나 앱 상에 계속적으로 노출시키는 역할을 합니다. 서버측 코드는 데이터베이스로 부터 데이터를 던지는 등 동적으로 새로운 컨텐츠들을 만듭니다. 반면에, 클라이언트측 자바스크립트는 새로운 HTML 표를 만들어 서버에서 요청한 데이터를 뿌려 사용자에게 보이는 등 동적으로 브라우저 안에서 작동됩니다. 이 둘 사이는 서로 미묘한 차이가 있지만, 서로 연관되어 있고 서버측 클라이언트측의 관계와 접근에 대해 알 필요가 있습니다.
동적으로 바뀌지 않는 페이지를 "정적"페이지라고 합니다. (항상 같은 콘텐츠를 보여줍니다.)
자바스크립트는 CSS와 같은 방식으로 HTML 페이지에 적용됩니다. CSS는 외부의 스타일시트를 적용하기 위해 link 요소를 사용하거나 내부의 스타일시트를 적용하기 위해 style 요소를 사용하는 반면,자바스크립트는 HTML상에서 오직 script 태크만으로 사용이 가능합니다. 어떻게 작동되는지 한번 살펴봅시다.
</body>
태그 직전에 다음의 코드를 추가하도록 합니다:
<script> // JavaScript goes here </script>
그러고 아래의 자바스크립트 코드를 <script></script>사이에 넣음으로서 페이지 상에서 동작이 가능하게끔 할 수 있습니다.( 위 코드에서 "// JavaScript goes here" 부분에 아래의 코드를 추가하면 됩니다.)
document.addEventListener("DOMContentLoaded", function() {
function createParagraph() {
let para = document.createElement('p');
para.textContent = 'You clicked the button!';
document.body.appendChild(para);
}
const buttons = document.querySelectorAll('button');
for(let i = 0; i < buttons.length ; i++) {
buttons[i].addEventListener('click', createParagraph);
}
});
각각의 문법에 대해서는 이후 더 자세히 다루기 때문에, 동작여부만 확인하고 넘어가도 무방합니다.
Note: 만약 예제가 실행되지 않는다면, 돌아가서 올바른지 한 번 더 체크해보도록 하세요. 혹시 저장할 때 확장자를 .html 로 하지 않았나요? 혹시 {{htmlelement("script")}} 를</body>
태그 뒤에 붙인 건 아닌가요? 다음과 같이 자바스크립트를 작성했나요? 자바스크립트는 까다로운 언어이기 때문에 정확하게 문법을 지킬 필요가 있습니다. 그렇지 않으면 제대로 동작하지 않을 수 도 있습니다.
Note: 깃허브에서도 이 코드를 볼 수 있습니다. apply-javascript-internal.html (see it live too).
만약에 외부 파일로 자바스크립트를 위치시키고 싶다면 어떻게 할까요? 이에 대해서 알아봅니다.
script.js
라는 새로운 파일을 만듭니다. 파일의 확장자가 .js이면 그 파일이 자바스크립트로 이루어져 있음을 뜻합니다.<script src="script.js" defer></script>
function createParagraph() {
let para = document.createElement('p');
para.textContent = 'You clicked the button!';
document.body.appendChild(para);
}
const buttons = document.querySelectorAll('button');
for(let i = 0; i < buttons.length ; i++) {
buttons[i].addEventListener('click', createParagraph);
}
Note: 깃허브에서 이 버전을 볼 수 있습니다. apply-javascript-external.html 그리고 script.js (see it live too).
실제 HTML 속에 포함된 자바스크립트코드를 함께 쓸 수 있습니다. 이는 다음과 같으니 참고해보세요:
function createParagraph() { let para = document.createElement('p'); para.textContent = 'You clicked the button!'; document.body.appendChild(para); } //HTML 내의 <scirpt>태그 내부에 작성
<button onclick="createParagraph()">Click me!</button>
이는 다음과 같은 예제로 볼 수 있습니다.
이 데모 예제는 <button>태그에 onclick속성에 대한 값을 함수이름으로 넣어 버튼이 클릭될 때마다 함수가 실행되도록 작성하였습니다.
하지만, 이 방법은 효율적이지 않습니다. 이는 자바스크립트와 함께 HTML 소스를 복잡하게 할 수 있습니다. 또한 함수를 만들기 위한 모든 버튼 마다 onclick="createParagraph()"
속성을 포함해야합니다.
JavaScript 코드만으로도 모든 버튼에 함수를 연결할 수 있습니다. 위의 내용을 의도한대로 수정한다면 다음과 같습니다:
const buttons = document.querySelectorAll('button'); //모든 <button>태그를 List 형태로 buttons 변수에 저장한다. for (let i = 0; i < buttons.length ; i++) { buttons[i].addEventListener('click', createParagraph); } //복수이기 때문에 for를 사용해 루프를 돌린다.
이 코드는 onclick 속성 코드 보다 조금 길어보이지만, 페이지가 많든, 버튼의 수가 많든 적든 상관없이 모든 버튼들이 같은 기능을 할 수 있도록 합니다. 물론 자바스크립트 코드를 변경할 필요가 없습니다.
Note: apply-javascript.html 수정을 해보고 버튼을 한 번 추가해 보세요.
실행해보면 버튼 하나하나 클릭할 때 마다 글이 보일 것입니다. 꽤 깔끔하지 않은가요?
작성된 스크립트를 브라우저가 적절한 때에 로딩하는것에 대해 몇가지 이슈가 있습니다. 중요한 것은 모든 HTML 요소는 순서대로 페이지에 로드된다는 것입니다. 만약 당신이 자바스크립트를 이용해 HTML 요소를 조작할 경우(정확하게는 DOM), 자바스크립트 코드가 조작 대상인 HTML 요소보다 먼저 실행된다면 조작할 요소가 존재하지 않는 상태이기 때문에 제대로 동작하지 않을 것입니다.
위의 코드 예제에서, 내부와 외부의 자바스크립트는 HTML Document의 body
가 해석되기 전인 head
부분에 로드되고 실행되었습니다. 이는 에러를 일으킬 수 있습니다. 그래서 여기에 사용되는 몇가지 해결방법들이 있습니다.
내부 자바스크립트 예제에서는 다음과 같이 구성하면 됩니다:
document.addEventListener("DOMContentLoaded", function() {
...
});
이 이벤트리스너는 "DOMContentLoad"
이벤트가 발생되었을 때 function()
을 실행한다는 의미입니다. (이벤트 리스너에 관해서는 이번 코스에서 다루게 됩니다.) "DOMContentLoad"
이벤트는 브라우저가 완전히 로드되고 해석될때 발생됩니다. function(){}
내부의 자바스크립트 구문은 이벤트가 발생되기 전까지는 실행되지 않습니다. 따라서 모든 body
태그의 요소가 로드된 이후 자바스크립트 코드가 실행되도록 만들어 에러를 피할 수 있습니다.
외부 자바스크립트 예제에서는 좀더 최신의 자바스크립트 문법인 async
속성을 사용하게 됩니다. 일반적으로 HTML
요소를 로딩하는 중 <scirpt>
태그를 만나면 JavaScript의 내용이 모두 다운될 때까지 HTML
로딩은 멈추게 되는데, async
요소는 비동기방식으로 <script>
태그에 도달했을 때 브라우저에게 HTML
요소를 멈추지 않고 다운받도록 유지시킵니다.
<script src="script.js" async></script>
이 경우 script
와 HTML
은 모두 동시에 로드되고 작동할 것입니다.
Note: 외부 스크립트 경우 async 속성을 사용하면 되기 때문에 내부 스크립트처럼 DOMContentLoaded이벤트를 사용할 필요가 없습니다. 하지만 async속성은 외부 스크립트의 경우만 동작합니다.
예전 방식은 scirpt
요소를 body
태그의 맨 끝에 넣는 방법이었습니다(</body>
바로 위에). 이 방식을 사용해도 body
태그가 모두 로드된 이후 scirpt
가 실행되게 만들 수 있습니다. 문제는 이 방법과 DOMContentLoaded
를 이용한 방법 모두 HTML DOM
이 로드되기 전까지 script
의 로딩과 파싱이 완전히 차단된다는 것입다. 이는 많은 자바스크립트 코드를 다루는 규모가 큰 사이트의 경우 사이트를 느리게 만드는 중요한 성능 문제를 야기할 수 있습니다. 이것이 async
속성을 사용해야 하는 이유입니다!
Note: 자바스크립트의 비동기 개념은 이해하는데 시간이 오래 걸리기 때문에, 지금 이해되지 않는다면 현재 단계에선 외부 스크립트 방식만 사용하고 넘어가도 무방합니다.
더 깊게 들어가보면 이러한 코드문제를 해결하기 위한 방법은 실제로 두가지가 있습니다. — async
와defer
입니다. 두 가지의 차이를 봅시다.
async 스크립트는 페이지 렌더링의 중단 없이 스크립트를 다운로드 하고, 또한 스크립트의 다운로드가 끝나자 마자 이를 실행시킵니다. async는 외부 스크립트끼리의 구체적인 실행 순서는 보장하지 않고, 단지 나머지 페이지가 나타나는 동안 스크립트가 비동기방식으로 다운로드 되어 중단되지 않는다는 것만 보장합니다. async는 각각의 스크립트가 독립적으로, 서로에게 의존하지 않는 관계일 때 적절합니다.
아래의 예제를 보시죠:
<script async src="js/vendor/jquery.js"></script>
<script async src="js/script2.js"></script>
<script async src="js/script3.js"></script>
3개의 스크립트를 로딩하지만 이들의 순서는 보장할 수 없습니다. 이는 script2.js
나 script3.js
에 있는 함수가 jquery.js
의 함수를 사용한다면 에러를 발생될 수 있다는 것을 의미합니다.
Defer는 이와 다르게 순서대로 다운로드 한 후 모든 스크립트와 내용이 다운로드 되었을 때 실행됩니다:
<script defer src="js/vendor/jquery.js"></script>
<script defer src="js/script2.js"></script>
<script defer src="js/script3.js"></script>
따라서 위의 예제의 경우에는 jquery.js
-> script2.js
-> script3.js
의 순서가 보장됩니다.
요약 :
async
를 사용합니다.defer
를 사용하고 각각의 <script>
태그들을 실행되길 원하는 순서대로 작성합니다.HTML과 CSS와 같이, 자바스크립트에서도 주석문의 사용이 가능합니다. 주석문은 브라우저 실행때는 무시되어 넘어가고 다른 개발자로 하여금 어떻게 구성되고 작동되는지 설명해주는 역할을 합니다(물론 자신의 훗날 코드를 다시 보았을 때 빨리 기억하고, 이해할 수 있게끔 도와주기도 합니다.). 주석문은 매우 유용하고 코딩시 자주 사용됩니다(특히 큰 프로젝트에서). 주석문에는 두가지 종류가 있습니다:
// I am a comment
/* I am also a comment */
예를 들자면, 앞의 데모예제에 주석문을 다음과 같이 달 수 있습니다.
// Function: creates a new paragraph and append it to the bottom of the HTML body. function createParagraph() { let para = document.createElement('p'); para.textContent = 'You clicked the button!'; document.body.appendChild(para); } /* 1. Get references to all the buttons on the page and sort them in an array. 2. Loop through all the buttons and add a click event listener to each one. When any button is pressed, the createParagraph() function will be run. */ const buttons = document.querySelectorAll('button'); for (let i = 0; i < buttons.length ; i++) { buttons[i].addEventListener('click', createParagraph); }
지금까지 우리는 자바스크립트의 첫걸음을 떼었습니다. 여기서 자바스크립트를 왜 사용하고 어떻게 사용하는지에 대한 방법들에 대한 기초적인 부분을 배웠습니다. 여러 예제 코드를 봄으로써, 웹사이트와 다른 곳에서의 코드상 자바스크립트가 어떻게 구성되어있는지 배웠습니다.
자바스크립트가 지금은 조금 어려울 수 있으나, 걱정하지 마세요. 이 수업은 첫 단계인만큼 앞으로 더 많은 것을 배우기 위해 감각을 키우기 위한 수업입니다. 다음 수업에서 우리는 plunge straight into the practical를 통해 앞으로 더 나아가고 스스로 자바스크립트 예제를 실행해볼 것입니다.