자바스크립트
IT위키
더 많은 작업
(JavaScript에서 넘어옴)
자바스크립트(JavaScript, JS)는 웹 브라우저 안에서 웹 페이지의 내용과 동작을 바꾸기 위해 만들어진, 동적 타입의 인터프리터형 스크립트 언어이다.
1995년 넷스케이프의 브렌던 아이크(Brendan Eich)가 만들었다. 이름에 '자바'가 들어 있지만 자바와는 문법 일부만 닮았을 뿐 다른 언어다. 표준 규격 이름은 ECMAScript(ECMA-262)이고, 자바스크립트는 그 구현체를 가리키는 이름으로 굳었다.
웹 페이지는 세 가지가 역할을 나눠 만든다.
자바스크립트는 브라우저가 문서를 객체 트리로 펼쳐 놓은 DOM을 읽고 고쳐서 화면을 바꾼다. 이렇게 페이지를 새로 받지 않고 화면을 바꾸는 기법을 묶어 DHTML이라 불렀고, 여기에 서버와의 비동기 통신을 더한 것이 Ajax다.
- 인터프리터 방식 - 브라우저의 자바스크립트 엔진(V8, SpiderMonkey 등)이 소스를 받아 바로 실행한다. 지금의 엔진은 실행 중 기계어로 컴파일(JIT)해 속도를 낸다
- 따로 컴파일해 두지 않는다 - 소스 코드(.js 파일이나 HTML 안의 스크립트)가 그대로 브라우저로 전달되므로 소스가 공개되고, 누구나 브라우저의 소스 보기로 읽을 수 있다. 숨겨야 할 로직이나 비밀 값을 넣지 않는다
- 사용자의 클릭·입력에 반응하는 인터랙티브(대화형) 웹 페이지를 만드는 데 쓴다
- 동적 타입 - 변수에 형을 선언하지 않고, 실행할 때 값에 따라 형이 정해진다
- 객체 기반·프로토타입 상속 - 클래스 대신 다른 객체(프로토타입)를 이어받아 객체를 만든다. ES2015 부터 class 문법이 들어왔지만 내부는 프로토타입이다
- 일급 함수 - 함수를 값처럼 변수에 담고 넘길 수 있다. 이벤트 처리에 콜백 함수를 많이 쓴다
- 이벤트 기반·단일 스레드 - 클릭·입력·타이머 같은 이벤트가 생기면 등록한 함수를 실행한다. 오래 걸리는 일은 비동기(Promise, async/await)로 처리한다
- HTML 문서 안에서는
<script>요소로 넣거나 외부 .js 파일을 불러온다
자바스크립트는 클래스가 아니라 프로토타입(Prototype)을 바탕으로 하는 객체지향 언어다. 모든 객체는 자기를 만든 원형 객체와 숨은 연결을 가지고, 자기에게 없는 속성은 그 원형에서 찾는다.
- 프로토타입 객체(Prototype Object) - 함수를 정의하면 함께 만들어지는 객체로, 그 함수를 생성자로 써서 만든 객체들이 함께 쓸 속성과 메서드를 담는다.
함수.prototype으로 가리킨다 - 프로토타입 링크(Prototype Link) - 각 객체가 자기 원형을 가리키는 숨은 연결이다. 명세에서는
[[Prototype]], 브라우저에서는__proto__로 보인다 - 프로토타입 체인 - 속성을 찾을 때 링크를 따라 원형, 원형의 원형으로 올라가며 찾는다. 이것이 자바스크립트의 상속이다
function Person(name) { this.name = name; }
Person.prototype.hello = function () { return "Hi, " + this.name; };
const p = new Person("Kim");
p.hello(); // "Hi, Kim" - p 에 없어 Person.prototype 에서 찾는다
Object.getPrototypeOf(p) === Person.prototype; // true
const q = Object.create(p); // 클래스 없이 p 를 원형으로 삼는 객체
q.hello(); // "Hi, Kim" - q → p → Person.prototype 순으로 찾는다
| 구분 | 클래스 기반(자바, C++) | 프로토타입 기반(자바스크립트) |
|---|---|---|
| 객체를 만드는 틀 | 클래스를 먼저 정의하고 그 인스턴스를 만든다 | 이미 있는 객체(프로토타입)를 원형으로 삼는다 |
| 상속 | 클래스가 클래스를 상속한다 | 객체가 프로토타입 링크로 다른 객체를 잇는다 |
| 실행 중 변경 | 클래스 구조를 바꾸기 어렵다 | 프로토타입에 메서드를 더하면 그 원형을 잇는 모든 객체에 바로 반영된다 |
- ES2015(ES6)부터
class,extends문법을 쓸 수 있지만, 프로토타입 상속을 클래스처럼 쓰게 해 주는 문법일 뿐 클래스 기반 상속으로 바뀐 것은 아니다. 위의Object.create처럼 클래스를 정의하지 않고도 상속이 된다 - 그래서 "자바스크립트는 클래스 기반 언어이므로 객체 상속은 클래스를 정의해야만 할 수 있다"는 틀린 설명이다 → 상속 (객체지향)
사용자 입력을 그대로 페이지에 넣으면 공격자가 심은 자바스크립트가 다른 사용자의 브라우저에서 실행된다. 이것이 크로스사이트 스크립트(XSS)다. 브라우저는 다른 출처의 문서에 스크립트가 접근하지 못하게 동일 출처 정책을 둔다.