자바스크립트 객체지향 프로그래밍 : jquery 구조 분석까지

75

Post on 22-Jul-2016

253 views

Category:

Documents


11 download

DESCRIPTION

황인균 지음 | 오픈소스 & 웹 시리즈 _ 040 | ISBN: 9788992939041 | 25,000원 | 2012년 07월 13일 발행 | 392쪽

TRANSCRIPT

Page 1: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지
Page 2: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지
Page 3: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

감사의 글

여보!

그동안 당신의 배려와 이해에 고맙다는 말 하고 싶어요.

회사 스트레스에도 불구하고 아이 키우는 것에도 함께 고민하고 신경을 써 주려고 애쓰는 것

에도 고마워하고 있어요.

나도 우리의 행복을 위해 오늘도 “나의 묘비명”을 고민하고 있어요.

사랑해요.

자랑스러운 아들!

아빠는 너만 생각하면 힘이 솟는단다. 잘 자라주어서 고맙고 앞으로도 잘 자라주기를 바란다.

넌 어디를 가든지 환영받는 아들이 될 거라 아빠는 믿어.

사랑해.

그리고 어머니!

우리 가정이 이렇게 행복한 것은 모두 어머니 때문이라는 것 알고 있어요.

어머니가 없었다면 우리 부부도 그렇고 준서도 그렇고 이렇게 행복하지는 못했을 거예요.

건강하세요.

Page 4: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

00들어가며

0.1 자바스크립트의 저평가 ……………………………………………………………………… 18

0.2 웹 개발 환경의 변화 ………………………………………………………………………… 19

0.3 이 책에서 다루는 내용 ……………………………………………………………………… 23

이 책의 내용 …………………………………………………………………………………… 23

대상 독자 ……………………………………………………………………………………… 25

0.4 이 책의 구성 …………………………………………………………………………………… 25

0.5 테스트 툴 ……………………………………………………………………………………… 28

파이어버그 설치 ……………………………………………………………………………… 28

파이어버그 실행 ……………………………………………………………………………… 29

01자바스크립트의 기본 개념

1.1 리터럴 …………………………………………………………………………………………… 34

1.2 변수 ……………………………………………………………………………………………… 35

Page 5: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

1.3 데이터 타입 ……………………………………………………………………………………… 35

1.4 var 변수 ……………………………………………………………………………………… 37

1.5 값 타입의 데이터와 참조 타입의 데이터 …………………………………………………… 38

1.6 프로그램 실행 단계 …………………………………………………………………………… 41

02자바스크립트의 기본 문법

2.1 원시 타입 ………………………………………………………………………………………… 48

숫자 ……………………………………………………………………………………………… 48

문자열 …………………………………………………………………………………………… 52

불린 ……………………………………………………………………………………………… 55

undefined와 null ………………………………………………………………………… 55

2.2 연산자 …………………………………………………………………………………………… 58

증가, 감소 연산자 …………………………………………………………………………… 58

비교 연산자 …………………………………………………………………………………… 59

논리 연산자 …………………………………………………………………………………… 62

Page 6: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

2.3 실행 제어 ……………………………………………………………………………………… 65

조건문 …………………………………………………………………………………………… 65

반복문 …………………………………………………………………………………………… 69

예외 처리 ……………………………………………………………………………………… 73

03자바스크립트의 함수

3.1 자바스크립트 함수의 역할 …………………………………………………………………… 78

3.2 함수 모델링 …………………………………………………………………………………… 79

3.3 함수 정의 - 3가지 방법 ……………………………………………………………………… 83

3.4 함수 인자 – arguments, callee ……………………………………………………… 84

3.5 Function ……………………………………………………………………………………… 88

3.6 함수 객체 ……………………………………………………………………………………… 92

3.7 익명 함수 ……………………………………………………………………………………… 96

3.8 중첩 함수 ……………………………………………………………………………………… 97

3.9 콜백 함수 ……………………………………………………………………………………… 98

Page 7: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

04변수 스코프

4.1 함수 단위의 변수 관리 …………………………………………………………………… 104

4.2 변수 스코프 객체 …………………………………………………………………………… 106

4.3 렉시컬 특성 ………………………………………………………………………………… 109

4.4 변수 스코프 체인 ………………………………………………………………………………111

4.5 루트 객체 ………………………………………………………………………………………113

4.6 클로저 ……………………………………………………………………………………………115

자바스크립트 클로저 …………………………………………………………………………116

클로저 인스턴스 I ………………………………………………………………………………119

05자바스크립트 객체

5.1 클래스 기반의 객체지향 …………………………………………………………………… 126

5.2 객체 생성 …………………………………………………………………………………… 130

5.3 Object객체 정의 I - new Object …………………………………………………… 133

5.4 Object객체 정의 II - 객체 리터럴 ……………………………………………………… 135

5.5 사용자 정의 객체 정의 III ………………………………………………………………… 138

Page 8: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

06자바스크립트 객체 멤버

6.1 객체 멤버 관리 ……………………………………………………………………………… 144

멤버 구분 …………………………………………………………………………………… 144

멤버 관리 구조 ……………………………………………………………………………… 145

멤버 접근, 관리 …………………………………………………………………………… 150

멤버 순회, 존재 확인 ……………………………………………………………………… 153

6.2 prototype, constructor, 인스턴스 ………………………………………………… 157

생성자, 프로토타입 객체, 인스턴스 관계도 …………………………………………… 157

프로토타입 객체 …………………………………………………………………………… 159

프로토타입 멤버 편집의 비대칭 ………………………………………………………… 163

프로토타입 객체 대체 …………………………………………………………………… 167

생성자 ……………………………………………………………………………………… 168

6.3 멤버 접근 제어 구조 ………………………………………………………………………… 170

비공개 멤버 구현 ………………………………………………………………………… 170

클로저 인스턴스 II ……………………………………………………………………………171

Page 9: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

07자바스크립트 상속

7.1 함수와 객체 정의 …………………………………………………………………………… 178

함수 정의 절차 ……………………………………………………………………………… 179

객체 생성 …………………………………………………………………………………… 180

this …………………………………………………………………………………………… 183

7.2 자바스크립트 상속 ………………………………………………………………………… 187

프로토타입 멤버 상속 ……………………………………………………………………… 187

프로토타입 체인 …………………………………………………………………………… 190

Object 멤버 ………………………………………………………………………………… 192

7.3 Function 상속 …………………………………………………………………………… 196

Function 프로토타입 멤버 ……………………………………………………………… 196

Function 상속 …………………………………………………………………………… 202

7.4 객체 확장 …………………………………………………………………………………… 206

프로토타입 멤버 상속 구현 - prototype ……………………………………………… 209

인스턴스 멤버의 상속 구현 - call/apply …………………………………………… 212

Page 10: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

상속 구현 통합 ……………………………………………………………………………… 214

멤버 확장 …………………………………………………………………………………… 217

7.5 리플렉션 ……………………………………………………………………………………… 218

타입 판별 - typeof 연산자 ……………………………………………………………… 219

상세 타입 판별 - instanceof 연산자 ………………………………………………… 221

사용자 정의 타입 판별 - toString 재정의 …………………………………………… 224

08내장 객체

8.1 배열 객체 …………………………………………………………………………………… 230

배열 생성 I – new Array ……………………………………………………………… 230

배열 생성 II – 배열 리터럴 ……………………………………………………………… 232

배열 객체의 데이터 구조 ………………………………………………………………… 233

Array 프로토타입 멤버 …………………………………………………………………… 235

Page 11: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

8.2 정규식 객체 ………………………………………………………………………………… 238

정규식 객체 생성 – RegExp, 정규식 리터럴 ………………………………………… 241

패턴 매칭 수행 - 정규식 객체 …………………………………………………………… 242

패턴 매칭 수행 - String ………………………………………………………………… 243

8.3 JSON ……………………………………………………………………………………… 245

JSON ……………………………………………………………………………………… 246

JSON 형식 ………………………………………………………………………………… 247

JSON 객체 사용 …………………………………………………………………………… 249

09자바스크립트 객체 응용

9.1 네임스페이스 구현 ………………………………………………………………………… 254

9.2 자동 호출 패턴 ……………………………………………………………………………… 257

9.3 싱글톤 패턴 구현 …………………………………………………………………………… 258

9.4 모듈 패턴 구현 ……………………………………………………………………………… 262

9.5 메서드 체인 패턴 구현 ……………………………………………………………………… 264

Page 12: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

10웹 브라우저 스크립팅

10.1 웹 브라우저 스크립팅 …………………………………………………………………… 268

웹 브라우저 스크립팅 환경 ……………………………………………………………… 268

이벤트 기반 프로그래밍 ………………………………………………………………… 274

웹 페이지 구성 요소 ……………………………………………………………………… 275

자바스크립트 코드 구성 …………………………………………………………………… 277

웹 페이지 로딩 ……………………………………………………………………………… 281

10.2 이벤트 핸들링 ……………………………………………………………………………… 286

이벤트 핸들링 ……………………………………………………………………………… 286

이벤트 핸들러 반환값 ……………………………………………………………………… 287

웹 이벤트 핸들러의 this ………………………………………………………………… 288

DOM Level 2 - 이벤트 전파 …………………………………………………………… 291

DOM Level 2 - 이벤트 핸들링 ………………………………………………………… 293

DOM Level 2 - Event 객체 ………………………………………………………… 297

브라우저 호환성 …………………………………………………………………………… 299

Page 13: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

11jQuery 프로그래밍

11.1 jQuery 학습 가이드 ……………………………………………………………………… 305

11.2 도입단계 : jQuery 개요 ………………………………………………………………… 307

jQuery 특징 ……………………………………………………………………………… 307

jQuery 함수, jQuery 객체 …………………………………………………………… 310

DOM 요소 선택 …………………………………………………………………………… 312

jQuery 메서드 체인 ……………………………………………………………………… 313

jQuery 요소 스택 ………………………………………………………………………… 314

11.3 개발 1단계 : 로드 이벤트 핸들러 ……………………………………………………… 315

11.4 개발 2단계 : 화면 요소 선택 …………………………………………………………… 319

선택식 기초 ………………………………………………………………………………… 319

선택식 확장 - 어트리뷰트 ………………………………………………………………… 324

선택식 확장 - 폼 요소 …………………………………………………………………… 325

선택식 확장 - 상태 기준 ………………………………………………………………… 328

문자열이 아닌 선택식 ……………………………………………………………………… 329

DOM 요소 접근 …………………………………………………………………………… 330

Page 14: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

.find(), .filter(), .end()………………………………………………………………… 331

.each(), jQuery.each() ……………………………………………………………… 333

11.5 개발 3단계: 요소 핸들러 등록 ………………………………………………………… 337

이벤트 핸들러 등록:.bind() …………………………………………………………… 337

이벤트 핸들링 헬퍼 함수 ………………………………………………………………… 340

이벤트 객체 ………………………………………………………………………………… 343

11.6 개발 4단계: 요소 조작 …………………………………………………………………… 345

값 조작 - 텍스트박스 - .val() ………………………………………………………… 345

값 조작 - 선택요소 - .val() …………………………………………………………… 346

값 조작 - 컨테이너 요소 - .text(), html() …………………………………………… 349

상태 조작 - .attr() ………………………………………………………………………… 350

상태 조작 - .show(), .hide() ………………………………………………………… 353

구조 조작 - .empty() …………………………………………………………………… 353

구조 조작 - .append(), .prepend() ……………………………………………… 354

구조 조작 - .clone() …………………………………………………………………… 356

클라이언트 캐시 - .data() ……………………………………………………………… 357

Page 15: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

11.7 개발 5단계 : 통신 ………………………………………………………………………… 358

jQuery.ajax() …………………………………………………………………………… 358

.load(), $.get(), $.getScript() ……………………………………………………… 361

11.8 심화 단계 : jQuery 라이브러리 분석 ………………………………………………… 365

jQuery 구조 ……………………………………………………………………………… 365

jQuery 함수 ……………………………………………………………………………… 368

jQuery 프로토타입 객체 ………………………………………………………………… 369

jQuery.fn -프로토타입 객체 확장……………………………………………………… 371

jQuery의 this 컨텍스트 ………………………………………………………………… 372

플러그인 제작 ……………………………………………………………………………… 376

커스텀 이벤트 ……………………………………………………………………………… 380

12참고 자료

도서 ………………………………………………………………………………………………… 384

훌륭한 웹문서……………………………………………………………………………………… 385

Page 16: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

들어가며

0

Page 17: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

0.1 - 자바스크립트의 저평가

0.2 - 웹 개발 환경의 변화

0.3 - 이 책에서 다루는 내용

0.4 - 이 책의 구성

0.5 - 테스트 툴

Page 18: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

18

0.1 자바스크립트의 저평가

자바스크립트! 참으로 오래된 인연이다. 필자가 주로 사용하는 언어가 포트란, C++, C#으로

바뀌는 동안에도 자바스크립트는 계속 필자의 옆을 지키고 있다. 처음 필자가 웹사이트를 만들

기 시작하면서부터 알아온 지 이제 10년이 넘어가고 있다. 그렇지만 다른 언어에 비해 이 언어

를 그렇게 잘 알고 있는 것 같지는 않다. 특히 자바스크립트가 객체지향을 지원한다는 사실은

오래전부터 알고 있었으면서도 시간을 내서 공부하고픈 생각은 들지 않았다. 왜 그랬을까?

우선은 자바스크립트를 이용해 객체지향적으로 코딩을 할 필요성이 별로 없었다. 지금까지는

“자바스크립트 코드에서 HTML 요소에 접근하려면 어떻게 해야 하고, 팝업창을 띄우려면 어떤

메서드를 사용해야 하는가”처럼 DOM 요소에 포함된 속성, 메서드를 아는 것이 중요했다. 즉,

객체를 직접 설계하거나 구현할 필요가 없었다. 대신 멋진 기능을 구현한 코드를 발견하면 별

도로 스크립트 코드 조각을 모아뒀다가 필요할 때 복사해서 붙여넣기만 잘하면 그만이었다. 그

저 복사해서 붙여넣기만으로도 자바스크립트가 담당하는 거의 모든 역할을 할 수 있었고, 그래

서 자바스크립트에 대한 편견이 있었으리라는 생각이 든다. 자바스크립트는 웹 클라이언트에

서나 사용되는 보조적인 존재라는 편견, 그래서 “그저 그런” 프로그래밍 언어로만 여겨졌을 것

이다.

자바스크립트는 웹 애플리케이션 개발에 있어 보조적인 언어라는 편견이 있었다.

자바스크립트가 저평가된 또 다른 이유를 찾자면 이 언어를 잘 설명한 표준 문서 또는 심도 있

는 도서가 부족하다는 것이다. 인터넷을 검색해보면 거의 모든 정보가 이럴 때는 이렇게, 저럴

때는 저렇게 하는 HOW-TO식의 코드 조각이거나 나름대로 부분적으로만 객체지향을 설명

하는 문서가 대부분이다. 자바스크립트의 객체지향적인 특징을 전체적으로 통일된 용어로 설

명한 문서가 없고, 언어의 내부를 설명한 문서는 더더욱 부족하다. 언어 스펙을 설명하는 문서

또한 어렵다. ECMA의 공식 명세서는 다음 링크에서 내려받아 읽어볼 수 있다.

http://www.ecma-international.org/publications/standards/Ecma-262.htm

Page 19: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

19

너무 어렵다. 문서가 불친절하기 그지 없다. 처음에는 필자의 영어 실력 부족을 탓했다. 그런데

영어권 사람에게도 이 문서가 어렵기는 마찬가지인 것 같다. 다음 블로그의 내용을 읽어보길

바란다. 한글로 번역된 페이지도 있다.

http://javascript.crockford.com/javascript.html

자바스크립트 분야에서 이 블로그의 주인장은 유명하다. 그러나 이 사람도 표준 문서를 발표한

ECMA, TC39 위원들에게 반성을 촉구하고 있다. 이렇게 표준 문서가 제대로 돼 있지 않으니

자바스크립트를 설명한 관련 서적도 형편없을 수밖에 없다. 프로그래밍 언어적인 차원에서 제

대로 된 참고 자료가 없으니 이 언어를 제대로 배우기가 어려웠던 건 어쩌면 당연한 일일지도

모른다.

자바스크립트를 제대로 설명한 문서가 부족했다.

0.2 웹 개발 환경의 변화

자바스크립트를 이용해 객체지향적 개발이 가능하다는 사실이 요즘 들어 왜 중요해졌는지는

웹 애플리케이션을 개발하는 개발자라면 모두 공감할 것이다. 웹 개발 환경의 변화를 몸으로

인식하고 있을 것이기 때문이다.

기존의 PHP, JSP, ASP.NET같은 서버 측 언어를 사용한 웹 애플리케이션은 비즈니스 로직을

구현한 코드가 서버에 있다. 따라서 서버 측 비즈니스 컴포넌트의 실행 결과가 필요하다면 서

버 측에 요청을 해야 한다. 그러나 비즈니스 컴포넌트의 서비스 결과를 요청할 때뿐만 아니라

사용자 화면(User Interface)을 일부 변경하기 위해서도 서버에 요청을 보내서 서버에서 처리

하는 경우가 많았다. 예를 들어, 사용자가 선택하는 조건에 따라 화면의 특정 부분이 변경돼야

한다면 사용자 선택 정보를 서버 측으로 전달하고 서버 측에서는 특정 부분을 변경한 HTML

코드를 포함한 전체 화면을 다시 보내주는 구조였다. 즉, 클라이언트 측 이벤트가 서버 측으로

전달되고 서버 측에서 이벤트를 처리하고 나서 다시 수정된 화면 전체가 클라이언트로 전달되

어 렌더링되는 모델이었다.

Page 20: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

20

이벤트 처리 결과 반환(HTML + 스크립트 코드 + 데이터)

브라우저

인터넷

웹 서버

이벤트 발생 이벤트 핸들러

그림 0.1 전형적인 웹프로그래밍 모델

이때 이벤트는 버튼 클릭처럼 사용자가 직접 발생시킬 수도 있고 로드 또는 언로드처럼 웹 페

이지의 라이프사이클상 발생하는 이벤트일 수도 있다. 이 같은 클라이언트 측에서 발생하는 이

벤트 정보는 HTTP 요청을 통해 서버로 전달된 다음 서버에서 처리된다. runat=“server” 어트

리뷰트가 있는 ASP.NET 컨트롤이 이벤트를 발생시키는 경우가 이런 구조에 해당한다. 서버

측에서 이벤트 처리 결과로 클라이언트에 보낼 것이 있다면 HTTP 요청에 대한 결과로 클라이

언트인 브라우저로 내려보내는 것이 전통적인 웹 프로그래밍 모델이었다. 전통적인 이벤트 처

리 구조에서는 이벤트가 발생할 때마다 불필요한 화면의 다른 상태 정보도 서버로 올라가고 또

한 HTML 그리고 스크립트 코드, CSS 내용 등이 계속 네트워크를 통해 함께 전달된다(물론 브

라우저 캐시를 이용해 이 문제를 완화할 수 있지만 이것은 프로그램 영역이 아니다). 따라서 성

능상의 문제가 불거진다.

물론 클라이언트에서 발생하는 이벤트를 클라이언트 측 스크립트로 처리하는 것도 이전의 개

발 모델에서 가능하다. 그러나 기존의 개발 모델에서 스크립트로 클라이언트 측에서 이벤트를

처리하는 것은 주로 데이터 유효성 검사 또는 간단한 애니메니션 효과를 주기 위한 목적이 대

부분이었다.

전통적인 웹 애플리케이션 개발 모델은 클라이언트의 이벤트가 서버에서 처리되고 그 결과가 반영된 전체 페이지

를 다시 내려받는 방식이었다.

하지만 이제는 사정이 달라졌다. Ajax를 이용하는 개발 모델에서는 화면 깜박임이 없고 좀 더

반응이 즉각적인 사이트를 경험할 수 있게 됐고, 사용자들은 이처럼 새로운 사용자 경험에 매

이벤트 전달(이벤트 정보 및 화면의 모든 상태 정보)

Page 21: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

21

료되기 시작했다. 구글 사이트는 스크립트를 이용해 이런 사용자 경험을 만족시키는 대표적인

예다. 이 모델을 그림으로 정리하면 다음과 같다.

데이터 요청

데이터 반환

브라우저

인터넷

웹 서버

이벤트 발생

이벤트 핸들러(.js)

데이터 요청 처리

그림 0.2 웹 프로그래밍 모델

Ajax를 이용하는 모델에서는 이벤트 핸들러가 클라이언트에 존재한다. 따라서 특정 이벤트가

발생하면 그것에 대한 클라이언트 측 핸들러가 실행되고 클라이언트 측 핸들러에서는 필요하

다면 서버 측에 페이지를 요청하는 것이 아니라 서버 측에 필요한 데이터를 요청한다. 서버 측

에서는 서버 측 플랫폼(자바, .NET 등)에 맞게 요청한 데이터를 구성해서 클라이언트로 내려

보낸다. 브라우저에서는 서버로부터 받은 데이터를 브라우저 페이지에 반영해 사용자에게 이

벤트 처리 결과를 보여준다. 결국 클라이언트에서 구현되는 코드는 화면에서 발생하는 이벤트

를 취해 서버에 요청을 보내고 보낸 요청에 대한 처리 결과를 받아 그 결과를 페이지에 동적으

로 반영하는 일을 한다. 웹 애플리케이션 화면은 레이아웃은 유지되면서 출력되는 데이터만 바

뀐다. 즉, 페이지 전체를 다시 서버 측에서 내려받지 않고 필요한 데이터만 받는다는 것이다.

Ajax를 이용한 개발 모델에서는 서버 측에 필요한 데이터를 요청해서 받은 후 화면 조작은 클라이언트에서 수행한

다. 이 모델에서는 페이지가 로딩되고 나면 페이지 전체를 다시 요청하지 않는다.

전통적인 웹 개발 모델이 서버와의 통신 방법으로 서브밋 또는 포스트백 방식을 기반으로 했다

면 이제는 웹 서비스를 기반으로 한다. 즉, 서버와의 통신에 Ajax를 사용하게 됨으로써 클라이

언트-통신-서버의 분리에 맞는 개발 모델이 확산됐다. 이러한 웹 개발 모델은 웹 서비스를 이

용하는 윈폼 애플리케이션 개발 모델과 거의 동일하다.

Page 22: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

22

윈폼과 Ajax의 UI(User Interface)는 한번 로딩되면 서버측의 서비스를 요청하기 위해 다시

리로딩될 필요는 없다. 앞에서 말한 것처럼 필요한 데이터가 있다면 웹 서비스를 통해서 내려

받는다. UI의 레이아웃은 그대로 유지될 수 있다. 더구나 요즘은 HTML5가 유행하면서 웹 애

플리케이션 개발 모델은 데스크톱의 윈폼 애플리케이션 개발 모델과 더더욱 비슷해지고 있다.

이런 모델에서 UI를 구성하고 서버와의 통신을 담당하는 요소, 이를테면 텍스트 박스, 드롭다

운 리스트 같은 폼 요소를 비롯해 파일 업로드 컨트롤, Ajax 통신, 다이얼로그 창 등은 단순히

HTML 태그로 여기기보다는 객체라는 관점에서 바라보게 된다.

이미 이전에도 HTML DOM(Document Object Model) 구조나 브라우저의 이벤트 모델은

객체지향적으로 코드를 작성할 수 있는 기반을 제공한다. 그러나 기존에는 전체 시스템에서 클

라이언트 측의 코드가 차지하는 비중이 적었다. 하지만 이제는 통신 방식의 변화로 클라이언트

측에서 구현해야 하는 업무 로직이 많아지고 코드의 양이 증가일로에 있다. 이러한 상황에서

자바스크립트가 하는 일과 코드의 양이 많아지면서 개발자의 코딩을 줄여주는 jQuery 같은 자

바스크립트 라이브러리가 등장하는 것은 당연한 일이다. 그리고 이러한 자바스크립트 라이브

러리에서는 대부분 큰 규모의 코드 덩어리를 구조화 및 모듈화할 목적으로 객체지향 기법을 적

극적으로 활용하고 있다.

결국 웹 애플리케이션 개발 모델 및 환경의 변화로 자바스크립트를 객체지향적으로 구현한 웹

애플리케이션 및 라이브러리를 점점 자주 접하게 될 것이다. 규모가 커질수록 코드를 유지 보

수하기 위해 기존의 객체지향 언어에서 검증된 디자인 패턴 및 코딩 패턴을 이용해 코딩할 수

밖에 없을 것이다. 이것이 자바스크립트에서 지원하는 객체의 특성과 구문, 그리고 패턴에 익

숙해져야 하는 이유다. 기존의 라이브러리나 코드를 분석하기 위한 목적뿐 아니라 개발, 디버

깅 그리고 기존 라이브러리를 확장하기 위해서도 객체지향적인 사고와 코딩 능력이 필요하다.

만약 재사용 및 확장성을 목표로 하는 라이브러리를 제작할 생각이라면 자바스크립트의 객체

지향적 특성을 이해하지 않고서는 불가능하다고 볼 수 있다.

Page 23: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

23

0.3 이 책에서 다루는 내용

이 책에서는 우선 자바스크립트를 웹 페이지에 동적인 효과를 추가하거나 입력 데이터의 유효

성 검사를 수행하는 등의 보조적인 수단이 아니라 클라이언트 측의 메인 로직을 구현하는 본격

적인 프로그래밍 언어로 간주한다.

프로그램을 작성하는 방법론 관점에서 보면 자바스크립트는 함수(function)를 위주로 프로그

래밍을 해 나가는 절차적 프로그래밍(procedural programming)과 함수를 비롯해 모든 것

을 객체로 간주해서 객체를 중심으로 프로그래밍을 해 나가는 객체지향 프로그래밍(object-

oriented programming) 방법을 모두 지원하는 언어다.

객체지향 프로그래밍 언어도 다시 클래스 기반의 프로그래밍과 프로토타입 기반의 프로그래밍

으로 나뉘는데, 자바스크립트는 프로토타입 기반의 객체지향 프로그래밍을 지원한다. 클래스

기반 언어에서는 클래스를 이용해 객체를 만들고 클래스를 기반으로 해서 상속을 지원하지만

프로토타입 언어에서는 객체의 원형(프로토타입)을 이용해 객체를 만들고 상속도 프로토타입

을 기반으로 한다.

자바스크립트에서 프로토타입을 정의할 때는 함수를 이용한다. 즉, 자바스크립트에서의 함수

는 프로토타입 기반의 객체지향 프로그램의 기본이 된다. 함수의 특성을 잘 알아야 자바스크립

트의 객체지향 특징을 제대로 이해할 수 있다. 따라서 이 책에서는 함수를 설명하는 데 많은 노

력을 기울였다.

이 책의 내용

이 책에서는 크게 다음과 같은 내용을 다룬다.

자바스크립트 함수의 정의 및 특성

이 책에서는 지금까지 호출만을 위해 사용해오던 자바스크립트 함수를 다른 관점에서 바라보

도록 유도할 것이다. 그래서 이 책에서는 함수가 그 자체로도 객체이면서 다른 객체를 생성할

수 있는 능력을 지닌 존재라는 사실을 상세히 설명할 것이다

Page 24: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

24

자바스크립트 객체의 정의 및 특성

또한 이 책에서는 자바스크립트 객체의 멤버를 어떻게 관리하는지 알아본다. 멤버 관리를 위한

데이터 구조를 알고 나면 자바스크립트에서 객체를 대상으로 작업할 때 사용하는 구문(이를테

면, 멤버에 접근할 때 [ ]을 사용하는 등)을 이해할 수 있을 것이다.

인스턴스 생성

인스턴스를 생성하는 절차와 관련해서 자바스크립트는 다른 클래스 기반의 객체지향 프로그래

밍 언어와는 사뭇 다르다. 인스턴스 생성 절차를 이해하면 자바스크립트 객체를 이해하는 데

크게 도움될 것이다.

객체 상속

객체지향에서 상속은 필수적이다. 자바스크립트에서 상속을 어떻게 지원하는지 알아본다.

자바스크립트 객체 응용

자바스크립트의 객체를 이용해 객체지향 프로그래밍에 필요한 네임스페이스와 디자인 패턴의

구현 방법에 관해 간단한 예제를 들어 설명한다. 이러한 패턴 예제는 뒤에서 소개하는 자바스

크립트 라이브러리에서도 응용된다.

자바스크립트 라이브러리

요즘 유행하는 다양한 자바스크립트 라이브러리는 모두 사용자 정의 함수 및 객체를 기반

으로 한다. 그러한 라이브러리의 예로 이 책에서는 jQuery를 분석해본다. jQuery의 구조

분석이 더욱 더 큰 목적이지만 먼저 라이브러리의 사용법을 알아봄으로써 자바스크립트

객체지향에 대한 궁금증을 유도하고 있다. 그리고 jQuery 라이브러리를 확장하는 방법을

알아볼 텐데, 확장이란 결국 자바스크립트 객체의 기본적인 특징을 이용하고 있다는 사실

을 알게 될 것이다.

이 책은 자바스크립트를 객체지향적으로 사용하기 위한 관련 문법을 설명하고 관련 개념

을 이해하는 데 목적이 있다. 그래서 이 책에서는 개념 이해를 돕고자 최대한 많은 그림을

사용하고 있다. 객체지향 개념을 말로만 전달하는 것은 위험한 일이다. 특히 자바스크립

Page 25: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

25

트로 구현된 객체지향 개념은 용어조차 너무 혼란스러워서 사람마다 다르게 받아들일 수

있다. 따라서 명확한 의미 전달을 위해 많은 그림을 넣으려고 노력했다.

대상 독자

자바스크립트 프로그래밍과 관련해서 다음과 같은 경험이 있다면 이 책이 도움될 것이다.

• 자바스크립트에서 함수의 개념 또는 역할이 이해되지 않는다고 느낀 적이 있다.

• 자바스크립트의 prototype 속성을 이해하려고 하거나 사용해 보려고 시도한 적이 있다.

• 자바스크립트의 변수와 변수 스코프를 이해하기 어렵다고 느낀 적이 있다.

• 클로저를 이해할 수는 있어도 직접 적용하기는 어렵다고 느껴본 적이 있다.

• 자바스크립트 라이브러리의 구현 코드를 보면서 이해하려고 노력해 본 적이 있다.

• 자바스크립트로 클래스를 정의하고 객체를 생성하는 방법이 다양해서 외우지 못하는 것은 물론 이해되지

않은 적이 있다.

• 자바스크립트로 클래스, 객체, 네임스페이스를 정의해 코드를 구조적으로 모듈화하는 데 관심이 있거나 직

접 시도해본 적이 있다.

• 자바스크립트 키워드인 this를 사용하기가 꺼려진다. 특히 HTML과 자바스크립트가 함께 사용될 때 this가

기존의 객체지향 언어에서 제공하는 this와 전혀 다르다고 생각한 적이 있다.

이 책을 자바스크립트 언어의 기본 문법에 대한 레퍼런스나 HTML DOM(Document Object

Model) 설명서 또는 웹 애플리케이션 개발 가이드로 생각하지 않길 바란다. 더 자세한 자바스

크립트 API 목록은 다른 웹 페이지를 참고한다.

0.4 이 책의 구성

앞에서 소개한 내용을 전달하고자 이 책은 다음과 같이 구성돼 있다.

1장. 자바스크립트의 기본 개념

자바스크립트의 객체를 설명하는 데 필요한 자바스크립트 구문과 개념이 있다. 1장에서는 리

터럴, 변수, 데이터 타입, var 변수, 값 타입과 참조 타입, 자바스크립트 프로그램 실행 단계 등

자바스크립트의 기본적인 구문과 개념을 설명한다.

Page 26: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

26

2장. 자바스크립트의 기본 문법

객체를 이해하려면 객체와 비교되는 다른 타입의 값(value)에 대해서도 알아둘 필요가 있다.

2장에서는 숫자, 문자열, 불린값과 같은 기본적인 값을 사용하는 방법을 비롯해 undefined,

null 같은 자바스크립트에서 제공하는 특수한 값들의 특성을 알아본다. 그리고 연산자, 조건

문, 반복문, 예외 처리 구문에서 다른 프로그래밍 언어와 비교했을 때 특이해 보이는 사항들을

중심으로 알아본다.

3장. 자바스크립트 함수

함수는 자바스크립트 객체지향에서 가장 중요한 개념이다. 호출 가능한 루틴이라는 전통적인

관점에서의 함수가 지닌 특징과 더불어 객체로서의 함수, 다른 객체를 생성하는 생성자로서의

함수를 설명한다.

4장. 변수 스코프

자바스크립트에서의 클로저는 일반 객체지향 프로그래밍 언어의 클래스와 가장 유사한 개념으

로 사용될 수 있는 요소다. 생성자(함수)로는 공개 멤버만 갖는 객체를 생성할 수밖에 없지만

클로저를 이용하면 비공개 멤버와 공개 멤버를 포함하는 객체를 만들어낼 수 있다.

이런 클로저는 특수한 구조를 갖는 함수로서 함수를 반환하거나 다른 객체를 반환하는 함수다.

클로저를 정확히 이해하려면 자바스크립트에서 지원하는 변수 스코프 및 변수 스코프 체인의 개

념을 이해하고 있어야 하며, 4장에서는 변수 스코프, 변수 스코프 체인, 클로저를 설명한다.

5장. 자바스크립트 객체

자바스크립트 객체지향 프로그래밍과의 비교를 위해 먼저 클래스 기반 객체지향 프로그래밍의

특징을 정리한다. 그러고 나서 객체를 정의하고 생성하는 데 사용하는 함수와 클래스와 객체의

특징을 각각 비교한다. 마지막으로 자바스크립트의 객체를 정의하고 생성하는 구문을 정리한다.

6장. 자바스크립트 객체 멤버

자바스크립트 객체의 가장 큰 특징 중 하나는 객체 멤버를 관리하는 방법이다. 6장에서는 객체

가 멤버를 관리하는 구조를 알아본다. 그리고 해당 멤버에 접근하거나 멤버를 추가, 대체하는

Page 27: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

27

등의 제어 방법을 알아본다. 또한 자바스크립트에서 아주 중요한 개념인 프로토타입 객체의 구

조와 개념을 알아본다. 그런 다음 클로저를 이용해 비공개 멤버를 가진 객체를 생성하는 방법

을 알아본다.

7장. 자바스크립트 상속

7장에서는 자바스크립트에서 지원하는 상속에 대해 자세히 알아본다. 자바스크립트에서 상속

이라고 하면 흔히 프로토타입 기반의 상속(prototypal inheritance)을 말한다. 프로토타입 상

속을 이해하려면 함수가 정의되는 과정에서 무슨 일이 일어나는지 알아야 한다. 따라서 7장에

서는 먼저 자바스크립트가 함수를 정의하는 내부적인 절차를 정리한다.

또한 이 책에서는 인스턴스 멤버 상속이라고 해서 프로토타입 멤버 상속과 구분해서 설명한다.

인스턴스 멤버 상속을 이해할 수 있게 인스턴스 생성 과정을 먼저 상세히 설명하고 객체 생성

과정에서 this가 어떻게 결정되는지 알아본다.

그리고 실제로 예제 코드를 통해 프로토타입 상속과 인스턴스 상속을 구현해 본다. 또한 일반

적인 객체의 상속뿐 아니라 함수의 상속에 대해서도 추가적으로 설명한다. 마지막으로 이미 생

성된 객체를 통해 해당 객체를 생성한 “타입”을 판별하는 방법을 알아본다.

8장. 내장 객체

자바스크립트에서 기본적으로 제공하는 내장 객체 가운데 배열 객체와 정규식 객체에 대해 알

아본다. 그리고 자바스크립트 문법에는 속하지 않지만 통신에서 전달되는 데이터를 표현할 때

흔히 사용되는 JSON 표기법에 대해서도 알아본다. JSON 표기법은 객체를 표현하기 위한 객

체 리터럴(object literal) 표현과도 유사하다.

9장. 자바스크립트 객체 응용

디자인 패턴을 이용하면 규모가 큰 라이브러리를 좀 더 조직적으로 만들거나 관리하기 쉬워진

다. 9장에서는 자바스크립트 객체를 응용해 네임스페이스 구현 및 기타 기본적인 패턴을 구현

하는 예를 알아본다.

Page 28: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

28

10장. 브라우저 스크립팅

앞 장까지는 실행 환경과는 상관없는 자바스크립트 언어만의 핵심적인 내용을 다뤘다. 10장에

서는 자바스크립트 프로그램의 실행 환경이 웹 브라우저인 경우에 대해 알아본다. 웹 브라우저

에서 자바스크립트 프로그램을 실행하는 환경과 관련된 사항을 알아보고 웹 브라우저가 지원

하는 이벤트 핸들링 모델을 설명한다. 아울러 크로스 브라우징, 즉 모든 브라우저에서 실행되

는 프로그램을 제작하는 것의 어려움을 알아본다.

11장. jQuery 프로그래밍

브라우저 호환성을 해결하는 한 방법으로 오픈소스로 제공되는 다양한 자바스크립트 라이브러

리를 이용할 수 있는데, 11장에서는 jQuery 라이브러리를 소개한다. 먼저 jQuery의 사용법을

설명하고 jQuery API를 살펴본다. 그러고 나서 최종적으로 jQuery 라이브러리의 구조를 분

석하고 jQuery를 확장하는 간단한 예를 보여준다. jQuery를 확장하는 예제를 통해 jQuery에

서도 자바스크립트에서 제공하는 프로토타입 객체의 특징을 이용하고 있다는 사실을 알게 될

것이다.

0.5 테스트 툴

요즘 유행하는 대부분의 웹 브라우저에는 자바스크립트 해석기가 내장돼 있다. 그래서 간단히

자바스크립트 코드를 텍스트 편집기에서 작성한 후 브라우저를 통해 실행해볼 수 있다. 또한

웹 브라우저에서 코드를 편집할 수 있는 애드온 툴을 제공하는 경우도 있어서 별도의 텍스트

편집기를 사용하지 않아도 된다. 예를 들어, 파이어폭스(Filerfox)에서는 파이어버그(Firebug)

라는 콘솔 툴을 설치해 코드 테스트에 이용할 수 있다. 우선 파이어폭스를 설치하고 나서 다음

페이지로 이동하면 다양한 종류의 애드온 툴을 설치할 수 있다.

https://addons.mozilla.org/en-US/firefox/

파이어버그 설치

이 페이지에서 CATEGORIES 아래의 Web Development 메뉴를 선택한다. 출력되는 애드

온툴 가운데 Firebug의 “Add to Firefox”를 선택하면 파이어버그가 설치된다.

Page 29: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

29

그림 0.3 파이어버그 설치

파이어버그 실행

� 파이어버그가 설치되면 그림처럼 브라우저 상단에 곤충 모양의 아이콘이 만들어진다. 이 아이콘을 클릭하

면 파이어버그 콘솔툴이 브라우저 하단에 나타난다. 또는 간단히 F12 버튼을 눌러 파이어버그를 실행할

수 있다.

그림 0.4 파이어버그 실행

Page 30: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

30

� 파이어버그의 우측 상단에 있는 버튼 가운데 “Open Firebug in New Window”를 클릭하면 독립된 창으

로 실행된다.

그림 0.5 새 창에서 파이어버그 실행

� Console 탭을 선택하면 코드를 한 줄씩 실행할 수 있는 창이 나타난다. 콘솔의 맨 아래에 있는 명령문 에

디터에 코드를 한 줄 입력하고 엔터를 누르면 코드가 실행되고 반환값이 콘솔에 출력된다. 코드는 현재 로

드돼 있는 페이지의 컨텍스트에서 실행된다. 따라서 그림처럼 document.location.href를 입력하면 현재

페이지의 URL이 반환된다.

코드를 입력하는 곳에서 위/아래 화살표 키를 누르면 이전에 수행한 코드를 다시 명령문 에디터로 가져

와서 실행해 볼 수 있다.

명령문 편집기에는 코드를 한 줄씩만 실행해볼 수 있다. 세미콜론(;)을 이용하면 여러 줄의 코드를 한 줄

로 입력해서 실행해 볼 수 있다. 하지만 코드를 여러 줄로 입력하고 싶다면 그림처럼 “Console” 탭 옆에

있는 화살표 버튼을 클릭한 후 메뉴에서 “Command Editor”를 선택하면 여러 줄을 입력할 수 있는 멀

티 에디터가 나타난다.

그림 0.6 파이어버그의 멀티 에디터 선택

Page 31: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

31

그림 0.7 파이버그의 멀티 에디터 실행

� 그러나 이 멀티 에디터를 실행하더라도 결과값으로 최종 반환값만 반환된다.

var v1 = 1;

var v2=2;

v1;

v2;

� 이렇게 멀티 에디터에 입력하고 실행(run)하면 최종적으로 반환된 v2의 값만 왼쪽 콘솔에 출력된다. 따라

서 파이어버그로 값을 출력할 때는 v1을 출력하는 코드를 실행하고 나서 다시 v2를 출력하는 코드를 실

행한다.

그림 0.8 파이어버그 콘솔 출력 #1

� 콘솔에서 v1, v2를 모두 보고 싶다면 console.debug( )를 사용하면 된다. 이 방법은 파이어폭스에서만 지

원된다.

그림 0.9 파이어버그 콘솔 출력 #2

console.debug( )를

통해 변수 값을 출력할

수 있다.

Page 32: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

자바스크립트의 기본 개념

1

자바스크립트의 객체를 설명하기 전에 필요한 기본적인 구문과

개념을 알아본다. 1장에서는 이러한 기본적인 구문과 개념을 설

명한다. 이러한 기본 구문과 개념으로는 리터럴, 변수, 데이터 타

입, var 변수, 값 타입과 참조 타입, 자바스크립트 프로그램 실행

단계 등이 있다.

Page 33: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

1.1 - 리터럴

1.2 - 변수

1.3 - 데이터 타입

1.4 - var 변수

1.5 - 값 타입의 데이터와 참조 타입의 데이터

1.6 - 프로그램 실행 단계

Page 34: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

34 1장 _ 자바스크립트의 기본 개념

1.1 리터럴

프로그램은 데이터를 가공하고 가공된 결과를 저장소(메모리, 파일, 데이터베이스 등)에 저장

하고, 다시 저장소에서 읽어와서 메모리에 올리는 등 실행되는 동안 수많은 데이터 가공 작업

을 하게 된다. 그런데 가공할 데이터의 값은 프로그램의 코드에 직접 표현돼 있기도 하고 외부

에서 전달받은 것도 있다.문자열 리터럴

var v=2 //숫자

var v="2" //문자열

var v='2' //문자열

var v=true //불린

이처럼 코드상에 직접 값이 표현되는 방식을 리터럴(literal)이라고 한다. 프로그램 코드상에서

리터럴을 이용해 값을 표현하는 방식은 데이터 타입별로 표현 방법이 다르다. 예를 들어, 코드

상에서 숫자를 나타낼 때는 단지 2로 표현한다. 인용부호로 둘러싸인 “2”로 표현하면 문자열을

나타내는 리터럴(string literal) 표현이다. 참, 거짓을 나타내는 값을 코드로는 true, false로 표

현한다. 이것은 불린 리터럴(boolean literals)이라고 한다. 프로그램의 코드에 직접 코딩돼 있

더라도 데이터의 타입에 따라 “리터럴” 표현이 다르기 때문에 프로그래밍 언어는 각 값의 타입

을 구분할 수 있다.

자바스크립트에는 모든 타입의 값을 코드상에서 표현할 수 있는 리터럴이 각각 존재한다. 앞에

서 보여준 것과 같은 숫자, 문자열, 불린값 외에도 객체, 배열, 정규식 객체를 나타내는 리터럴

표현도 있다.

{p1:2, p2:"2"} //객체의리터럴표현

[1,2,3,4] //배열객체의리터럴표현

코드에 이런 표현이 섞이면 자바스크립트 해석기는 해당 표현을 객체, 배열로 인식해서 메모리

에 구성한다. 이렇게 리터럴로 코드에 표현되는 값은 프로그램에서 고정된 값을 갖게 된다.

코드상에서 데이터 값을 표현하는 방식을 리터럴이라고 한다. 자바스크립트의 모든 데이터 타입에는 리터럴 표현

이 있다.

Page 35: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

1.3 데이터 타입 35

1.2 변수

프로그램에서 데이터의 값을 리터럴 값으로만 표현할 수밖에 없다면 프로그램은 존재할 수 없

다. 아래 코드를 보자.

alert((1+2)+3);

이렇게 간단한 연산의 경우에는 결과를 출력하는 과정에서 중간값을 다른 곳에 임시로 저장해

둘 필요가 없다. 그러나 복잡한 연산을 수행할 때 이렇게 리터럴 표현만으로 연산을 수행할 수

는 없다. 중간 단계의 값을 어딘가에 임시로 저장해야 한다.

v = 1+2;

alert(v+3);

v처럼 값을 임시로 저장할 수 있는 요소를 변수(variable)라고 한다. 프로그램이 실행되면 변

수는 메모리에 공간을 차지하게 된다. 변수의 값이 메모리에 임시로 저장되려면 메모리 공간을

할당받게 되는데, 얼마만큼의 공간을 할당받아야 하는지가 결정돼야 한다. 그러한 정보를 제

공하는 것이 바로 데이터 타입(data types)이다. 프로그램 언어는 자체적인 데이터 타입(data

type)을 제공하는데, 그러한 데이터 타입에 따라 메모리에 생성되는 변수의 크기가 결정된다.

변수의 메모리 크기는 데이터 타입에 따라 결정된다.

1.3 데이터 타입

메모리에 변수를 위한 공간을 생성할 때는 얼마만큼의 크기로 생성해야 하는지가 결정돼야 한

다. 이것은 모든 언어에서 필요한 정보다. 컴퓨터 프로그램은 근본적으로 숫자 3.14 또는 문자

열 “hello world”같은 값(value)을 조작하는 방식으로 작동한다. 변수의 크기 및 조작 방식은

값의 타입에 따라 달라진다.

모든 프로그래밍 언어는 각자 지원하는 기본적인 데이터 타입이 있다. 자바스크립트 또한

다른 언어에서도 지원하는 3가지 기본적인 원시 데이터 타입(primitive data type)인 숫자,

Page 36: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

36 1장 _ 자바스크립트의 기본 개념

문자열, 불린 타입을 지원한다. 그리고 null과 undefined라는 2가지 추가적인 데이터 타입

을 지원한다. 자바스크립트는 내부적으로 숫자, 문자열, 불린을 각각 “number”, “string”,

“boolean”으로 구분해서 관리한다. 즉, 모든 종류의 숫자를 내부적으로는 “number”로만

인식한다는 것이다.

1, 1,2, 0xff

모든 종류의 숫자를 내부적으로 “number”로만 인식한다는 것은 모든 수가 동일한 크기의 변

수에 저장된다는 의미다.

자바스크립트에서는 원시 데이터 타입으로 숫자, 문자열, 불린 그리고 null, undefined를 정의하고 있다.

자바스크립트도 객체지향을 지원하는 만큼 다른 객체지향 프로그래밍 언어에서처럼 객체

(object)라는 데이터 타입을 지원한다. 숫자, 문자열 같은 원시 타입과 객체가 모여서 다른 객

체를 구성할 수 있다. 객체를 구성하는 멤버에는 고유한 이름이 부여돼 있어서 그 이름으로 접

근할 수 있다. 따라서 각 구성 값이 정렬돼 있을 필요는 없다. 한편, 객체 중에는 객체를 구성하

는 멤버의 이름이 없는 대신 넘버링되어 순차적으로 구성될 수도 있다. 이 경우 객체를 구성하

는 특정 값에 접근하려면 숫자, 즉 인덱스를 이용한다. 이처럼 정렬된 객체의 구성값에 인덱스

를 통해 접근할 수 있는 객체를 배열(array)이라고 한다.

자바스크립트에서 객체 타입만큼 중요한 데이터 타입이 있는데, 바로 함수(function) 객체다.

뒤에서 알아보겠지만 함수는 여러 가지 역할을 한다. 흔히 알고 있는 호출 가능한 루틴으로서

의 함수를 비롯해 데이터로서의 함수, 다른 객체를 생성하는 요소로서의 함수가 있다. 함수도

객체이긴 하지만 역할에 따라 자바스크립트 언어에는 함수를 다루는 특별한 문법이 정의돼 있

다. 이 밖에도 날짜/시간(Date), 정규식(RegExp) 같은 타입이 있다.

원시 타입 : 숫자, 문자열, 불린, null, undefined

객체, 배열

함수

기타 : 날짜, 정규식 등

Page 37: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

1.4 var 변수 37

1.4 var 변수

자바스크립트에서 변수를 선언할 때는 var를 사용한다. 그래서 흔히 “var 변수”라고 부르기도

한다.

var a;

var a,b;

var a=1, b=2;

두 번째 예처럼 같은 var를 이용해 여러 개의 변수를 선언할 수도 있다. 또는 세 번째 예처럼

변수를 선언하면서 초기값을 할당할 수도 있다. 한 문장이 종료됐음을 나타내기 위해 세미콜론

(;)으로 마무리짓는다. 세미콜론을 붙이는 것은 반드시 필요한 것은 아니지만 좋은 습관이다.

자바스크립트가 다른 일반 언어와 다른 점은 var 변수에 어떤 타입의 값이라도 할당할 수 있다

는 점이다.

var v1=1;

v1="하나";

자바스크립트의 var 변수에는 문자열, 숫자 같은 기본적인 타입의 값뿐만 아니라 어떠한 사용

자 정의 객체라도 할당할 수 있다. 이것이 가능한 이유는 다른 언어와는 다른 타입 체계를 채용

했기 때문이다. 자바스크립트를 흔히 약한 타입의 언어(weakly typed language)라고 한다.

약한 타입의 언어는 강력한 타입의 언어(strongly typed language)와 대비되는 용어로서 강

력한 타입의 언어에서는 변수를 선언할 때 반드시 변수의 타입도 선언해야 하고 변수가 받아들

일 수 있는 값의 타입도 선언된 타입과 일치해야 한다. 정수형 변수, 문자형 변수라고 표현하면

그 변수에는 정수형 데이터, 문자형 데이터만 입력할 수 있다. 따라서 강력한 타입의 언어에서

는 어떤 변수를 대상으로 하는 연산이 가능한지 여부를 컴파일러가 사전에, 즉 컴파일하기 전

에 알 수 있다. 강력한 타입의 언어에서는 다음과 같이 컴파일하기 전에 변수의 타입을 선언해

야 한다.

정수형v1=1;

문자열형v2="2";

v2+v1 ;

Page 38: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

38 1장 _ 자바스크립트의 기본 개념

필요하다면 언어에 따라 v2+v1을 수행하기 위해 타입 변환이 일어날 수도 있다. 강력한 타입

의 언어에서는 이런 타입 변환이 가능한지도 컴파일할 때 판별된다. var 변수, 약한 타입 체계,

강력한 타입 체계의 특징을 다음 절에서 계속 알아본다.

1.5 값 타입의 데이터와 참조 타입의 데이터

변수에 데이터를 할당하는 것은 나중에 그 값을 다시 사용하기 위해서다. 변수 공간에 할당된

값을 다시 프로그램 코드에서 사용하게 되는 과정을 좀 더 자세히 상상해보자.

a.num = 3;

b="3";

c = a.num+b;

프로그램을 실행하다가 c=a.num + b 문장을 만났다고 하자. 자바스크립트는 우선 + 연산에

사용되는 좌우측 피연산자의 최종 값을 찾아가게 될 것이다. a.num의 값을 찾아가보자. “.” 연

산자 때문에 a가 가지고 있는 속성 중에서 num을 찾는다. 그래서 그 값을 + 연산자의 좌측 값

으로 사용하게 된다.

이러한 연산 과정에서 자바스크립트는 변수의 공간에 있는 값을 최종값으로 사용할 것인지(b

의 경우) 아니면 다른 메모리를 참조하는 값으로 판단해야 할지(a의 경우)를 결정할 수 있어야

한다. 즉, 변수에 있는 데이터가 값 타입(value type)인지 참조 타입(reference type)인지 알

수 있어야 한다.

자바스크립트에서 제공하는 값 타입의 데이터는 숫자(number), 문자열(string), 불린

(boolean)이 있고 조금 특수하게 “정의되지 않음”, “객체가 없음”이 있다. 이런 값 타입 데이터

를 제외하고 자바스크립트에서 제공하고 사용자가 정의한 타입은 모두 참조 타입의 데이터라

고 보면 된다.

자바스크립트에서 제공하는 값 타입의 데이터로는 숫자(number), 문자열(string), 불린(boolean),

그리고 “정의되지 않음”, “객체가 없음”이 있다.

다시 자바스크립트 입장이 되어 세 번째 식에서 사용되는 변수의 최종 값을 검색하는 과정으로

돌아가보자. 자바스크립트는 우선 연산에 사용된 변수 a, b가 값 타입 변수인지 참조 타입 변

Page 39: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

1.5 값 타입의 데이터와 참조 타입의 데이터 39

수인지 판별한다. 그래서 a는 참조 타입이라고 판단하게 되고 해당 참조값이 가리키는 메모리

로 이동해서 num이라는 것을 찾는다. num을 찾으면 그것이 값 타입의 데이터라는 것을 알게

되고, 그럼 num이 가지고 있는 값을 반환한다. b는 값 타입의 데이터라는 판단을 하게 되고,

b에 저장된 데이터를 곧바로 반환한다. 반환된 두 값은 + 연산에 사용하게 된다. 자바스크립트

는 + 연산에 사용되는 두 데이터의 타입이 좌측은 숫자, 우측은 문자열이라는 사실을 알게 된

다. 그러면 자바스크립트가 가지고 있는 타입 간의 변환 규칙에 따라 숫자인 3을 문자열로 변

환한다. 결국 다음과 같은 연산이 된다.

c = "3" + "3";

자바스크립트 엔진이 a.num, b의 최종값을 찾아가는 절차를 그림으로 그려보면 다음과 같다.

값 타입, 참조 타입 결정참조가 가리키는

위치로 이동속성, 메서드

검색

구체적인 타입 결정(숫자, 문자,데이터형)

필요하면 타입 변환

값 사용

참조 타입

값 타입

그림 1.1 a.num , b 검색 절차

이것이 자바스크립트에서 변수의 최종 값을 찾아 사용하는 절차다. 자바스크립트가 사용하는

약한 타입 체계에서는 num이 a 객체의 멤버인지는 사전에 알 수 없고 알 필요도 없다. a가 가

리키는 곳으로 실제로 이동해서 그곳에 멤버 num이 있는지를 알게 되는 시기는 프로그램이

실행되는 런타임이 되고 나서다.

약한 타입 체계의 언어에서는 런타임이 돼서야 객체의 멤버가 존재하는지 확인할 수 있다.

Page 40: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

40 1장 _ 자바스크립트의 기본 개념

이에 비해 강력한 타입 언어에서는 변수의 타입이 컴파일할 때 결정된다. 이것은 변수의 데이

터 구조가 사전에, 즉 실행되기 전에 파악할 수 있다는 의미다. 컴파일할 때 a 객체의 구조가

파악되면 num이 a의 멤버인지 알 수 있다. 따라서 컴파일 단계에 a에 없는 num2 같은 멤버

를 사용하면 컴파일 에러를 개발자에게 보여줄 수 있는 것이다.

자바스크립트에서 변수값을 검색해나가는 과정이 실행 단계에 수행된다는 것은 var 변수가 어

떤 타입의 데이터라도 받아들일 수 있다는 이론의 근거로 볼 수 있다. 이런 이유로 자바스크립

트에서는 객체에 없는 멤버를 조회할 때도 컴파일 단계에서는 에러가 발생하지 않고 실제로 실

행해봐야 에러를 볼 수 있다.

뒤에서 다시 언급하겠지만 자바스크립트 객체의 멤버는 모두 var 변수다. 속성과 메서드라는

용어는 객체지향과 관련된 용어로서 사람들의 커뮤니케이션에 편의를 제공할 뿐이다. 자바스

크립트 엔진 입장에서는 속성, 메서드, 변수를 구분하지 않는다. 모두 var 변수로서 값 타입이

냐 참조 타입이냐만 구분할 수 있으면 된다.

이처럼 런타임이 되어서야 타입을 확인한다는 것이 바로 약한 타입 체계의 특징이다.자바스크립트 객체의 멤버(속

성, 메서드)는 모두 var 변수다.

예를 들어, name, setNewName을 멤버로 포함하는 사용자 정의 타입인 Person이 있다고 하

자. 이것의 인스턴스를 생성한 후의 그림을 그리면 다음 그림과 비슷할 것이다.

+ name : …

+ setNewName :

+ name : "달봉이"

+ setNewName :

Person

함수

mySon 인스턴스

생성

실행 코드

그림 1.2 Person 인스턴스

Page 41: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

1.6 프로그램 실행 단계 41

mySon 인스턴스의 name 속성은 값타입의 변수이고 setNewName 메서드는 참조타입의 변

수다. 변수 setNewName이 함수를 가리키고 있는 참조타입의 변수라는 것도 런타임에 확인

할 수 있다. 즉 자바스크립트가 이 코드를 만나면 우선 변수 setNewName이 가리키는 곳으로

이동하고 그런 다음 연산자 “( )” 때문에 그 위치에 정의된 코드 블록을 실행한다. 만약 그러한

코드 블록이 없다면 에러가 발생하는 것이다.

만약 name( )처럼 name에 ( )를 사용해 name( )처럼 코드를 작성하더라도 컴파일할 때 에러

가 발생하지는 않는다. 실제로 프로그램을 실행할 때 name이 가리키는 곳에 가봤더니 그곳에

실행할 수 있는 코드 블록이 없다는 사실을 알게 되면 에러가 발생한다. mySon도 해당 객체에

대한 참조값이 할당된 var 변수다.

자바스크립트 객체의 멤버는 런타임에 존재 여부 및 멤버 타입(속성, 메서드)을 확인할 수 있다.

1.6 프로그램 실행 단계

인스턴스가 메모리에 생성되는 과정은 일반 강력한 타입의 언어와 자바스크립트가 조금 차이

가 있다. 이 약간의 차이로 일반 언어의 관점으로는 이해할 수 없는 상황이 연출되기도 하고 때

로는 일반 언어를 기준으로 자바스크립트 코드를 이해하려 하면 디버깅할 때 고생하는 경우가

발생할 수 있다.

프로그램

파싱

변수, 함수 정의

실행

함수 코드 파싱

호출함수 호출

그림 1.3 자바스크립트 프로그램의 실행 절차

Page 42: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

42 1장 _ 자바스크립트의 기본 개념

자바스크립트 프로그램을 시작하면 바로 프로그램이 실행되는 것이 아니라 프로그램의 전역

레벨에서의 파싱 단계를 거친다. 전역 레벨에서의 파싱이란 어떤 함수에도 포함되지 않은 변

수와 어떤 함수에도 포함되지 않는 이름 있는 함수(named function)에 대해 함수명과 동일한

변수를 만들고 이 변수를 실행 코드가 담긴 함수에 대한 참조로 초기화하는 것을 말한다. 앞으

로 ‘함수명과 동일한 이름의 변수’를 함수 변수라고 하자.

파싱 단계를 마치고 나면 프로그램이 실행되는데, 프로그램을 실행하다가 함수 호출을 만나면

해당 함수 레벨의 파싱 단계를 반복한다. 즉, 함수의 코드에서 그 함수의 지역 변수와 함수 변

수를 정의하고 나서 비로소 함수 코드를 실행한다. 함수 호출을 만날 때마다 이런 파싱과 함수

실행이 반복되면서 프로그램을 끝까지 실행한다.

파싱을 마치고 나면 해당 레벨의 var 변수와 함수 변수가 정의된다. 이 단계에서 코드 블록은 실행되지 않는다.

좀 더 정확히 말하면 전역 레벨의 파싱 단계에서 정의되는 변수와 함수 변수는 사실 루트 객체,

즉 웹 브라우저에서 프로그램이 실행되는 환경이라면 Window 객체의 멤버로 추가된다. 그리

고 함수 레벨의 파싱에서는 해당 함수와 연결돼 있는 변수 스코프라는 객체의 멤버로 추가된

다. 사실 루트 객체도 최상위 변수 스코프 객체다.

“객체의 멤버로 추가”된다는 것이 지금은 무슨 말인지 이해하기 어려울 수도 있다. 지금은 이렇

게만 이해해 두자. 모든 변수, 즉 var 변수든 함수 변수든 그것이 속하는 객체가 있다. 프로그

램에서 어떤 함수에도 속하지 않는 var 변수와 함수가 있다면 이것들은 런타임에 루트 객체에

속하게 되고, 함수에 속하는 변수와 내부 함수는 해당 함수와 연결된 변수 스코프 객체에 속하

게 된다. 함수의 변수 스코프 객체에 대해서는 “변수 스코프” 장에서 자세히 다루겠다.

프로그램의 모든 var 변수와 함수 변수는 그것과 연관된 변수 스코프 객체의 멤버로 추가된다.

다음의 간단한 예제 코드를 통해 파싱 단계에서 무슨 일이 일어나는지 알아보자.

//파싱단계에서변수x가메모리에undefined로정의됨.

//런타임에0이할당됨

var x = 0;

Page 43: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

1.6 프로그램 실행 단계 43

//파싱단계에서변수add가정의되고함수의코드블록에대한참조가할당됨

//파싱단계에서는함수구현코드가실행되지는않음

funcntion add(a,b) {

//런타임에지역변수c에a+b의값이할당됨

var c = a+b;

return c;

}

자바스크립트는 위 코드를 파싱하면서 코드에서 x와 add를 정의한다. 전역 변수 x는

undefined로 초기화되고 add 변수는 실행 코드가 담긴 함수의 참조로 초기화된다. 파싱 단계

를 마치고 런타임이 되면 이전에 정의된 변수와 함수를 사용해 작성한 문장이 실행된다. 그럼

이제 다음과 같은 코드를 보자.

alert(square(4)); //16출력

var square=0; //파싱할때정의된square변수를런타임에덮어쓴다.

function square(x){ //함수정의

return x*x;

}

alert(square); //0출력

이 과정을 그림으로 그리면 다음과 같은 절차로 실행된다.

undefined return x*x ;

alert(square(4));

var square = 0;

alert(square); return x*x ;

0

① ②

⑤코드 블록 코드 블록

square

컴파일(파싱) 코드 실행 실행 후

가비지 컬렉팅

square

그림 1.4 자바스크립트 프로그램의 실행 단계

코드를 실행하면 파싱 단계에서 전역 변수인 square와 함수인 square가 정의된다. 먼저

square 변수가 정의되고(①) 다음으로 square 함수가 정의되면서 square 변수를 덮어쓰게 된

다(②). 자바스크립트에서는 변수 square와 함수 square를 메모리에 정의할 때 변수와 함수를

구분해서 별도로 관리하지 않는다. 관리하는 장소가 동일하므로 이름이 같으면 덮어쓰게 된다.

Page 44: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

44 1장 _ 자바스크립트의 기본 개념

따라서 최종적으로 함수를 가리키는 square만 남게 된다. 여기까지가 파싱 단계에서 일어나는

일이다.

이제 코드가 실행되는 단계를 알아보자. square는 함수를 정의하고 있는 코드 블록을 가리

키고 alert(square(4));를 실행하면 16이 출력된다(③). 그러나 그다음 문장인 var square=0;

을 통해 square가 가리키고 있는 메모리에는 0이 할당된다(④). 따라서 마지막 문장인

alert(square)는 0을 출력한다(⑤).

자바스크립트에서는 변수와 함수를 구분해서 관리하지 않는다. 함수를 변수에 할당하든 변수

를 함수에 할당하든 정상적인 작업이다. 따라서 컴파일할 때 함수와 변수는 언제든지 다른 함

수와 변수에 의해 내용이 바뀔 수 있다.

자바스크립트에서는 변수명과 함수명을 별도로 구분해서 관리하지 않는다. 동일한 이름의 변수 또는 함수를 정의

하면 이전에 정의된 내용을 덮어쓴다.

개인이 혼자 개발할 때는 변수명과 함수명을 같은 이름으로 명명하지 않을 것이다. 그러나 여

러 사람이 함께 작업을 하거나 라이브러리를 사용하는 경우에는 이런 상황이 발생할 수 있다.

따라서 네임스페이스가 필요하다. 자바스크립트에서는 기본적으로 네임스페이스를 지정하는

방법을 제공하지 않으므로 직접 네임스페이스를 코딩해야 하며, 네임스페이스를 만드는 방법

은 뒤에서 알아보겠다.

Page 45: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지
Page 46: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

객체를 이해하려면 객체와 비교되는 다른 타입의 값에 대해서도

알아둘 필요가 있다. 2장에서는 기본적인 값, 즉 숫자, 문자열, 불

린값을 사용하는 방법을 비롯해 undefined, null 같은 자바스크립

트에서 제공하는 특수한 값의 특성을 알아본다. 그리고 연산자,

조건, 반복, 예외를 처리하는 구문에서 다른 프로그래밍 언어와

비교했을 때 특이하다고 생각되는 점을 중심으로 알아본다.

2장에서는 자바스크립트 언어의 특징적인 문법 위주로 설명한

다. 자세한 자바스크립트 문법은 자바스크립트 튜토리얼(http://

www.w3schools.com/js/default.asp)을 참고한다.

자바스크립트의 기본 문법

2

Page 47: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

2.1 - 원시 타입

2.2 - 연산자

2.3 - 실행 제어

Page 48: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

48 2장 _ 자바스크립트의 기본 문법

2.1 원시 타입

앞에서 구분한 데이터 타입 가운데 먼저 원시 타입(primitive data type)을 알아본다. 자바스

크립트에서의 객체 및 배열, 함수 그리고 정규식 객체는 뒤에서 살펴보겠다.

숫자

제목을 “Number”라고 하지 않고 “숫자”라고 했다. 여기서 한 가지 구분해둘 사항이 있다. 뒤

에서 설명하겠지만 “Number는 자바스크립트에서 사전에 정의(built-in)해 놓은 문법상의 표

현이고, “숫자”는 일반적인 의미의 수를 의미한다.

이 책에 나오는 “Number”와 “숫자”는 다른 의미다.

숫자를 프로그램에서 나타내는 방법으로는 앞 절에서 언급한 리터럴(literal) 표현도 있고 별로

사용하지는 않지만 Number 객체를 이용하는 방법이 있다. 사용 빈도가 낮더라도 앞에서 말한

것처럼 Number가 코드상에서 숫자를 표현할 수 있는 방법이라는 것과 이 절의 뒤에서 설명하

겠지만 Number가 “숫자 객체”를 만들 수 있는 한 방법이라는 점을 알아 두는 것은 자바스크립

트의 객체지향을 이해한다는 차원에서 의미가 있다.

자바스크립트에서 숫자는 정수(123), 실수(12.3), 8진수(0으로 시작하는 숫자, 0377), 16

진수(0x 또는 0X로 시작하는 숫자, 0x00) 등 다양한 형식으로 표현할 수 있지만 모든 숫

자는 실수(floating-point value) 값으로 해석된다. 표현 가능한 범위의 수는 최대 ±

1.7976931348623157x10308 그리고 최소 ±5x10-324다.

정수표현:var n1 = 255;

실수표현:var n2 = 255.0;

8진수표현:var n3 = 0377; // 3x64 + 7x8+7=255(10진수)

16진수표현:var n4 = 0xff : // 15x16+15=255(10진수)

프로그램 코드에 직접 나오는 숫자를 “숫자 리터럴(numeric literal)”이라고 한다. 앞에서처럼

프로그램에 나오는 숫자 리터럴의 표현 방식은 다르지만 변수 n1, n2, n3,n4 모두 내부적으로

는 실수 255를 값으로 갖는다. 리터럴 표현을 만나면 자바스크립트 해석기는 우선 실제 값으로

Page 49: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

2.1 원시 타입 49

계산한 다음 변수에 저장한다. 그리고 n1, n2, n3, n4의 타입, 즉 typeof 연산자의 값은 모두

“number”로 나온다.

typeof n1, typeof n2, typeof n3, typeof n4 "number"

이런 숫자는 문자열로 변환될 수 있다. “123” + 123 같은 수식을 만나면 자동으로 숫자를 문자

열로 변경해서 + 연산을 수행한다. 따라서 다음과 같은 결과가 나온다.

var v = "123"+123;

typeof v "string"반환

v "123123"반환

한편 자바스크립트의 숫자 타입에는 Infinity와 NaN이라는 특수한 값이 있다.

Infinity

자바스크립트에는 앞에서 본 최대 숫자를 벗어나는 숫자를 표현하기 위해 Infinity라고 하는

값이 정의돼 있다. 실제로 Infinity의 타입은 “number”로 나온다.

typeof Infinity "number"반환

자바스크립트에서는 숫자를 0으로 나누는 경우에도 Infinity를 반환한다.

var v = 1 / 0;

v Infinity반환

자바스크립트에서 지원하는 최솟값을 벗어나는 숫자를 표현하고 싶다면 –Infinity를 사용하

면 된다.

var i = -Infinity;

i -Infinity반환

typeof i "number"반환

typeof -Infinity의 반환값이 “number”라는 것을 보면 자바스크립트는 이것도 숫자로 인식

한다는 사실을 알 수 있다.

Page 50: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

50 2장 _ 자바스크립트의 기본 문법

Infinity와의 어떠한 산술 연산도 결과값으로 Infinity가 반환된다.

Infinity * 3 Infinity반환

Infinity – 999999999 Infinity반환

NaN

자바스크립트에는 NaN(Not A Number)라는 특수한 값도 있다. 이 또한 숫자값이다.

typeof NaN "number"반환

var a = NaN;

a NaN반환

숫자가 아닌 값이 산술 연산의 피연산자로 사용되면 연산 결과로 NaN이 반환된다.

var a = 10 * "f";

a NaN반환

NaN은 비교 연산에서 약간 이상하게 작동한다. 어떤 숫자와도 비교 연산을 할 수 없을 뿐더러

심지어 자신과도 비교 연산이 되지 않는다. 따라서 NaN == NaN을 실행하면 false가 반환된

다. 따라서 자바스크립트에서는 어떤 값이 NaN인지 확인할 때 쓰는 isNaN( )이라는 함수를 제

공한다.숫자값이 NaN인지 확인하려면 이 함수를 사용해야 한다. isFinite( )라는 함수도 있는

데, 이 함수는 인자가 NaN, Infinity, -Infinity이면 false를 반환한다. 그 밖에 앞에서 말한 표

현 가능한 자리의 수인 경우는 true를 반환한다.

var v=NaN;

isNaN(v) ; true반환

isFinite(v); false반환

v = 1;

isFinite(v); true반환

Math

자바스크립트에서는 단순한 산술 연산 외에도 복잡한 수학 연산을 위한 연산자를 하나의 Math

객체에 구현해 놓고 있다. Math 객체에 정의된 연산자에는 다음과 같이 접근할 수 있다.

var sinx = Math.sin(x);

Page 51: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

2.1 원시 타입 51

Math에는 다음과 같은 형식의 속성과 메서드가 포함돼 있다.

표 2.1 Math 객체의 멤버

속성 설명 사용 예

PI 원주율값 (약 3.14) Math.PI

SQRT2 2의 제곱근값(약 1.414) Math.SQRT2

메서드 설명 사용 예

abs(x) 절댓값 반환 Math.abs(-7.25)

ceil(x) 근접한 정수로 올림한 값 반환 Math.ceil(1.4)

다음 웹 페이지에 자세한 Math에 대한 속성, 메서드가 설명돼 있으니 참고한다.

http://www.w3schools.com/jsref/jsref_obj_math.asp

Number

자바스크립트에서는 Number라는 객체를 제공하는데, Number는 원시 타입의 숫자를 객체

로 만들기 위한 래퍼다. Number 객체를 이용하면 Object에서 정의한 멤버(속성, 메서드)를

사용할 수 있고 거기에 더해 Number에서 추가로 정의한 멤버를 사용할 수 있다. 숫자에 대한

Number 객체를 생성하는 방법은 다음과 같다.

var o = new Number(number);

표 2.2 Number 객체의 멤버

속성 설명 사용 예

MAX_VALUE 최댓값(양수) var v=Number.MAX_VALUE;

v; 1.7976931348623157e+308 출력

MIN_VALUE 0에 가까운 최솟값(양수) var v=Number.MIN_VALUE;

v; 5e-324 출력

NEGATIVE_INFINITY -Infinity를 나타냄 var v= Number.NEGATIVE_INFINITY;

v; -Infinity 출력

POSITIVE_INFINITY Infinity를 나타냄 var v= Number.POSITIVE_INFINITY;

v; Infinity 출력

Page 52: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

52 2장 _ 자바스크립트의 기본 문법

메서드 설명 사용 예

toString([radix]) Object의 toString( )을 오버라이딩한 메서드 var num=new Number(15);

num.toString( ); // 15를 10진수로 출력

15

num.toString(2); // 2진수로 출력

1111

num.toString(8); // 8진수로 출력

17

num.toString(16); // 16진수로 출력

f

valueOf( ) Number 객체가 래핑하고 있는 숫자 반환 var num=new Number(15);

num.valueOf( ) ;

15

Numer 객체의 모든 속성과 메서드에 대한 설명은 다음 페이지를 참고한다.

http://www.w3schools.com/jsref/jsref_obj_number.asp

Number는 숫자 객체를 생성하는 데 사용되기도 하지만 값을 숫자로 변환하는 데도 사용할 수

있다.

var v1 = new String("9");

Number(v1); 9반환

var v2 = "9";

Number(v2); 9반환

var v3="구";

Number(v3); NaN반환

숫자가 아닌 값이 인자로 전달되면 반환값은 NaN가 된다.

문자열

자바스크립트 프로그램에서 문자열을 표현하는 방법은 앞서 설명한 숫자처럼 리터럴 표현과

객체 표현이 있다. 문자열 객체를 표현하기 위해 String이라는 타입을 자바스크립트에서 제공

하고 있지만 실제로 코드를 작성할 때는 리터럴 표현을 주로 사용한다.

Page 53: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

2.1 원시 타입 53

var s = "hello world";

문자열 값을 갖고 있는 변수 s는 문자열 변수이고, 프로그램 코드에 직접 포함된 “hello

world”는 문자열 리터럴(string literal)이다. 프로그램상에서 문자열을 표현하기 위해 String

을 다음과 같이 사용할 수 있다.

var o = new String("hello world");

new String( )으로 반환된 값은 문자열이 아니라 객체다. String이 new와 함께 사용되어 문자

열 객체를 생성하는 데 사용되기도 하지만 new 없이 String( )만 사용되면 toString( )처럼 값

을 문자열로 변환하는 데도 사용될 수 있다.

var v1=new Date();

String(v1); "Wed Apr 04 2012 00:45:59 GMT+0900"반환

var v2 = 1234;

String(v2); "1234"반환

자바스크립트는 문자열을 유니코드 문자로 인식하고, 작은 따옴표(‘) 또는 큰 따옴표(“)로 둘러

싸서 표현한다. 작은 따옴표로 감싸면 문자열 중간에 큰 따옴표를 포함시킬 수 있고, 작은 따옴

표로 감싸면 작은 따옴표를 포함시킬 수 있다.

문자열 리터럴은 한 줄로만 표현할 수 있다. 만약 두 줄로 문자열을 포함시키고 싶다면 두

번째 줄 앞에 \n 같은 특수 문자를 사용해야 한다. 이러한 문자를 이스케이프 문자(escape

character)라고 한다.

"3.14"

"name='dalbong2'"

'I\'m happy'

'이문자열은\n두줄로나타난다'

세 번째 예처럼 작은 따옴표로 묶인 문자열 내부에 다시 작은 따옴표를 넣고 싶다면 작은 따옴

표 앞에 백슬래시(\)를 추가해야 한다. 큰 따옴표의 경우도 마찬가지다.

앞에서 사용된 예문에는 이스케이스 문자인 \n, \’가 있었다. 이때 백슬래쉬(\)는 아스키 코드

의 본래 의미가 아닌 다른 의미를 가진다. 이스케이프 문자는 백슬래시와 문자로 돼 있지만 하

Page 54: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

54 2장 _ 자바스크립트의 기본 문법

나의 문자 상수로 취급한다. 이스케이프 문자는 두 가지 기능을 제공한다. 모니터, 프린터 같은

주변 기기를 제어하는 데 사용하거나(\n) 인용 부호(‘, “) 안에서 표현될 수 없는 특수한 문자를

표현하는 목적(\’)으로 사용될 수 있다.

만약 백슬래시(\)를 사용하지 않고 n만 사용하면 자바스크립트는 n을 문자열의 일부로 여길 것

이고, ‘I’m happy’처럼 \를 없애고 ‘만 사용하는 경우에는 에러가 발생한다.

var v='I'm happy';

v; SyntaxError: missing ; before statement

다음은 ECMA-262에 정의된 다른 이스케이프 문자다.

표 2.3 이스케이프 문자

이스케이프 문자 이름 의미

\b Backspace 앞으로 한 칸 이동

\t Horizontal tab 수평 탭 간격만큼 이동

\n New line(개행문자) 다음 줄의 현재 수평 위치로 이동

\v Vertical tab 수직 탭 간격만큼 이동

\f Formfeed 새 페이지로 이동

\r CarriageReturn 현재 행의 처음으로 이동

\” Double quote 큰 따옴표 출력

\’ Single quote 작은 따옴표 출력

\\ Backslash 백슬래시 출력

자바스크립트에서는 문자열을 조작할 수 있게 subs t r ing ( ), toLowerCase ( ),

toUpperCase( ), replace( ), concat( ) 등 여러 API를 제공한다. 문자열 조작과 관련된 API

는 다음 웹 페이지를 참조한다.

http://www.w3schools.com/jsref/jsref_obj_string.asp

search( ), match( ), split( ), replace( ) 같은 메서드는 정규식 객체를 설명할 때 다루겠다.

Page 55: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

2.1 원시 타입 55

불린

불린(boolean) 값은 참과 거짓밖에 없다. 자바스크립트에서 불린값을 프로그램에서 표현하려

면 true, false를 사용하면 된다. true, false는 불린 리터럴(boolean literal)이다. Boolean이

라는 객체 생성자를 제공하고 있지만 코드를 작성할 때는 거의 사용되지 않는다.

var b = false; //거짓값을리터럴로표현

var b = new Boolean(); //거짓값을갖는불린객체

자바스크립트 해석기가 코드를 분석하다가 참과 거짓을 판단해야 하는 코드를 만나면 반드시

true/false만을 근거로 하지는 않는다. 비교문의 평가 결과를 근거로 판단하기도 하고 다른 결

과값을 근거로 불린 값을 평가하기도 한다. 불린 값을 평가하는 규칙은 다음과 같다. 비교 결과

가 0, null, “”(빈 문자열), false, undefined, NaN 이외의 값으로 평가되면 항상 “참”으로 해

석된다. 불린값 평가 규칙은 “비교 연산자” 절에서 다시 한 번 자세히 설명하겠다.

undefined와 null

undefined

변수를 선언하면 먼저 undefined 값이 할당된다.

var v = 1;

이 코드에서 변수 v는 먼저 undefined로 정의되고 코드를 실행하는 단계에서 다시 1로 초기화

된다. 아직 값을 할당하지 않은 상태에서 해당 변수를 사용하려고 하면 undefined가 반환된

다. undefined는 “값이 정해지지 않음”이라는 의미를 나타내기 위해 특별히 정의한 값이다.

undefined는 “값이 할당되지 않음”을 나타내는 특별한 값이다.

함수를 호출할 때 매개변수에 값을 전달하지 않으면 해당 매개변수는 undefined가 된 상태에

서 호출된다. 값이 할당되지 않은 변수, 할당되지 않은 함수 매개변수, 그리고 할당되지 않은

객체의 멤버는 undefined로 초기화된다.

Page 56: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

56 2장 _ 자바스크립트의 기본 문법

v1; ReferenceError: v1 is not defined

var v2;

v2; undefined반환

var obj = {};

obj.p; undefined반환

v1은 아예 정의되지 않은 변수의 값을 출력하려 하고 있다. 이런 경우에는 에러가 발생한다. v2

변수는 선언은 했지만 아직 다른 값을 할당하지 않았으므로 자바스크립트에서 자동으로 할당

한 undefined가 출력된다. 세 번째 예는 객체를 생성해서 속성 p를 추가하는 코드다. 이 코드

에 대해서는 뒤에서 자세히 다룬다. 그러나 속성 p에는 아직 값을 할당하지 않았다. 따라서 자

바스크립트에서 자동 할당한 undefined가 출력된다. 만약 undefined가 다른 값으로 변환돼

야 한다면 상황에 따라 달라질 수 있다.

표 2.4 undefined 변환값

변환 타입 반환값

불린 false

숫자 NaN

문자열 “undefined”

다음과 같은 코드에서는 if 문에서 undefined가 불린값으로 변환된다.

var v1;

if(v1) {

//실행코드

}

v1의 값은 undefined이고 불린값을 요구하는 if문의 조건식에서 undefined는 false로 판정되

기 때문에 if 문의 코드 블록은 실행되지 않는다.

null

null은 “객체가 없음”을 나타내는 특별한 값이다. 변수를 선언하면 “값이 정해지지 않음”을 표

현하기 위해 자동으로 undefined가 할당된다고 했다. 자동 할당된 undefined라는 값을 변경

Page 57: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

2.1 원시 타입 57

하려면 코드에서 수동으로 값을 할당해야 한다. 즉, null은 코드를 통해 명시적으로 할당하는

값으로서 undefined와는 구분되는 값이다.

null과 undefined 비교

undefined 값은 사실 루트 객체(global object)에 undefined라는 속성으로 정의돼 있다. 이

속성값을 통해 undefined 값에 접근하는 것이다. 뒤에서 배우겠지만 자바스크립트 객체의 속

성이나 메서드는 제거할 수 있다. 누군가가 루트 객체의 속성인 undefined를 제거하거나 다른

값을 할당해 놓으면 문제가 발생할 수 있다.

그러나 null은 자바스크립트의 키워드로 정의돼 있다. 쉽게 말하면 자바스크립트에 null로 “하

드 코딩”돼 있어서 프로그램에서 없애거나 변경할 수 없다는 것이다. 따라서 안정된 라이브러

리를 만들려고 한다면 라이브러리가 실행되면서 전역 변수에 undefined가 정의돼 있는지 확

인하는 코드를 수행하고 그 값을 undefinded로 초기화하는 것이 좋다. 그러자면 다음과 같이

동일한 이름의 변수를 선언하는 코드면 충분하다.

var undefined;

undefined 변수를 전역 변수 스코프에 이렇게 선언하고 값을 할당하지 않으면 루트 객체, 즉

전역 객체에 undefined 속성이 정의되고 그 값이 undefined로 초기화되는 것을 보장할 수

있다.

undefined 속성에는 이처럼 값을 할당할 수 있다. undefined의 이러한 불완전성 탓에 변수

를 선언하면 우선 null로 초기화하게 하는 것이 안전한 코딩 습관이다. 설령 그 값이 나중에 초

기화되더라도 null로 초기화하는 습관을 들이는 것이 좋다.

두 특별한 값과 관련해서 특이한 사항은 비교 연산(==)을 하면 같다는 결과가 나온다는 것

이다.

var u;

var n = null;

u == n; true반환

u === n; false반환

Page 58: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

58 2장 _ 자바스크립트의 기본 문법

undefined == null의 연산 결과는 참이 된다. 그렇지만 두 피연산자의 값뿐만 아니라 타입까

지도 비교하는 “===” 연산자를 이용해 undefined === null 연산을 하면 거짓이 반환된다.

비교 연산자 ==, ===에 대해서는 “비교 연산자” 절을 참조한다.

2.2 연산자

앞에서 설명한 데이터의 값을 가공하기 위해 프로그래밍 언어에는 많은 연산자가 정의돼 있다.

값을 더하고 빼는 등의 산술 계산을 하기 위한 산술 연산자와 두 데이터가 같은지 판단하는 데

사용하는 비교 연산자, 그리고 and, or를 연산하는 논리 연산자가 있다. 이 절에서는 연산자별

로 유의해야 할 사항만을 정리한다.

증가, 감소 연산자

++를 증가 연산자라고 하는데, 다음처럼 좌측의 표현은 증가 연산자를 이용해 우측의 식처럼

표현할 수 있다.

year = year +1 year++;

이 연산자의 정확한 동작은 그것의 위치에 따라 달라진다. 증가 연산자를 ++year처럼 변수 앞

에 사용한다면 변수값을 먼저 증가시키고 증가된 값을 연산의 최종값으로 평가한다. 그리고 증

가 연산자가 year++처럼 변수의 뒤에 사용된다면 증가하기 전의 값이 연산에 사용된 다음에

변수의 값이 증가한다. 즉 ++은 피연산자 변수의 값을 증가시키기는 하지만 증가값 반환 시점

은 연산자의 위치에 따라 달라진다.

증가 연산자의 위치에 따라 증가값 반환 시점이 달라진다. 변수 앞에 사용되면 변수의 값을 먼저 증가시킨 후 반환

해서 연산에 사용한다. 변수 뒤에 사용되면 증가되지 않은 값을 연산에 사용한 후 변수 값을 증가시킨다.

다음 두 경우에서 변수 i, j의 값을 확인해보자.

i = 1;

j = ++i;

Page 59: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

2.2 연산자 59

i; 2반환

j; 2반환

i=1;

j=i++;

i; 2반환

j; 1반환

화살표로 결과를 보여주고 있다. ++i는 변수에 1을 먼저 더하고 그 결과값을 반환하는 반면

i++는 변경되기 전의 값을 반환하고 나서 1을 더하기 때문에 이런 결과가 나온다. 그럼 다음

연산의 결과를 예상해보자.

var v = 0;

(++v) +1 ; 2반환

v; 1반환

var v = 0;

(v++)+1; 1반환

v; 1반환

감소 연산자인 --도 마찬가지다. 다음의 함수는 어떤 값을 반환할까?

function decrease(count) {

return count--;

};

decrease(10); 10반환

함수 decrease는 count 값을 먼저 반환한 다음 count 값에서 1만큼 감소시킨다. 결과값으로

10이 출력된다.

비교 연산자

비교 연산자에는 ==(equal), ===(identical)가 있는데, 두 연산자의 차이점에 대해 알아보

자. 다음 == 연산의 결과는 어떤 값이 반환될까?

var b = (1 == "1"); // true 반환

Page 60: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

60 2장 _ 자바스크립트의 기본 문법

== 연산자는 두 피연산자의 타입이 다른 경우는 타입을 일치시키고 비교하기 때문에 이런

결과가 나오는 것이다. 즉, 숫자 1을 “문자열”로 변환한 다음(자바스크립트의 규칙이다) 비교

한다.

1과 “1”을 다르게 판단하고 싶다면 === 연산자를 사용해야 한다. === 연산자는 타입 변환을

하지 않고 타입과 값을 모두 비교한다. 숫자형과 문자열형으로 타입이 다르기 때문에 === 연

산자는 false를 반환한다.

== 연산자는 피연산자의 타입이 다르면 타입을 먼저 일치시켜 비교한다.

=== 연산자는 타입 변환을 하지 않는다.

표 2.5 동등 연산자 비교

연산자 설명 예

== 피연산자의 타입이 서로 다른 경우 비교하기 전에 같은 타입으로 변환한 후 값을 비교한다. 1==’1’ true 반환

=== 피연산자의 타입을 변환하지 않은 상태에서 타입과 값이 모두 같은 경우 true를 반환한다. 1===’1’ false 반환

!= 타입을 변환한 후 피연산자의 값이 같지 않으면 true를 반환한다. 1 !=’1’ false 반환

!== 피연산자의 타입을 변환하지 않은 상태에서 값이 같지 않거나 또는 타입이 다르면 true를 반

환한다.

1 !==’1’ true 반환

다음과 같은 비교를 보자.

var s = "hello";

var o = new Object("hello");

s == o; true반환

예제의 경우처럼 문자열(또는 숫자, 불린값)과 객체를 비교하면 객체의 값(valueOf( ))을 비교

한다. 다음처럼 피연산자가 객체라면 두 객체의 참조값을 비교한다.

var o1 = new String("hello");

var o2 = new Object("hello");

o1 == o2; false반환

Page 61: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

2.2 연산자 61

==, ===의 피연산자로 객체가 올 경우, 참조값이 일치하면, 즉 두 참조값이 가리키는 메모리

상의 객체의 위치가 같다면 true가 반환된다.

==, ===의 피연산자로 객체가 올 경우 두 참조값이 가리키는 메모리의 위치가 같다면 true를 반환한다.

이번에는 다음 코드를 실행하지 말고 먼저 결과를 예상해보길 바란다.

var a= ["1","2","3"];

var b = ["1","2","3"];

a==b ; true or false ?

var a= ["1","2","3"];

var b = [a[0],a[1],a[2]];

a==b; true or false ?

["1","2","3"]==["1","2","3"]; true or false ?

리터럴 표현을 사용하고 있기 때문에 약간 망설여질 수 있지만 다음처럼 생성자를 이용하는 표

현으로 변경하면 좀 더 편하게 추측할 수 있을 것이다.

var a = new Array(1,2,3);

var b= new Array(1,2,3);

a==b; true or false ?

앞의 비교식은 모두 false를 반환한다. 흥미로운 점은 일부 특수한 경우에는 특이한 결과가 나

온다는 것이다. NaN 값은 어떤 것과 비교해도, 심지어 NaN 자신과 비교해도 false를 반환한

다.

NaN == NaN false반환

그리고 undefined와 null을 비교하면 true로 나온다.

undefined == null true반환

Page 62: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

62 2장 _ 자바스크립트의 기본 문법

논리 연산자

일반 언어에서는 논리 연산자(||, &&, !)의 양쪽에 모두 불린값을 반환하는 표현만이 올 수 있

다. 그리고 결과값 또한 불린값(true/false)이 반환된다. 그러나 자바스크립트에서는 이런 작동

방식이 약간 달라진다.

if 문의 조건식을 평가하는 부분에서 언급하겠지만 자바스크립트에서는 조건식을 평가한 결과

값이 0, “”, null,undefined, NaN 같은 값을 제외하고는 모두 참을 반환한다. 이것이 의미하

는 바는 논리 연산의 양쪽에 객체가 피연산자로 나와서 평가 대상이 될 수 있음을 의미한다.

“객체 || 객체”와 같은 표현이 가능하다는 것이다.

자바스크립트의 || 연산자나 && 연산자를 쓸 때는 각 피연산자의 평가 결과가 연산자의 최종

반환값이 된다는 점에 주의한다.

obj1 || obj2 연산결과로 반환되는 값은 true, false가 아니라 좌측 또는 우측 피연산자의 최종 평가값이 된다.

OR 연산자(||)

먼저 OR 연산자인 ||부터 알아보자.

var result=좌측피연산자||우측피연산자

연산자 ||의 좌측 피연산자를 평가해서 참으로 나오면 우측 피연산자는 평가하지 않고 좌측

피연산자의 최종 평가값을 반환한다. 즉, 0, “”, null,undefined, NaN이 아닌 평가값을 그대

로 반환한다는 것이다. 만약 좌측 피연산자가 거것으로 평가되면 우측 피연산자의 최종 평가값

을 그대로 반환한다. 다음과 같은 예에서 변수 a에 할당되는 값을 예상해보자.

var a=(1+2)||{};

변수 a에 true가 할당될 것이라고 예상했다면 다시 한번 생각해보길 바란다. 변수 a에는 3

이 할당된다. 다른 예제 코드를 보자. 함수 내부의 oEvent에는 어떤 객체가 할당될지 예상

해 보자.

Page 63: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

2.2 연산자 63

function validateField(oEvent){

oEvent = oEvent||window.event;

//이하생략

}

validateField( ) 함수의 경우, 함수 인자로 넘어오는 oEvent가 null이 아니면 “=”의 좌측 변

수인 oEvent에 함수 인수 oEvent가 가리키는 참조가 할당된다. 만약 함수 인자인 oEvent가

null인 경우는 우측 피연산자인 window.event가 그대로 반환된다. 만약 window.event도

null이라면 null 그대로 반환된다.

결국 validateField( ) 코드는 다음과 같은 의미로 풀이할 수 있다.

function validateField(oEvent)

{

if(oEvent == null) oEvent = window.event;

}

AND 연산자(&&)

이제 AND 연산자 &&를 알아보자.

var result=좌측피연산자&&우측피연산자

AND 연산자인 &&는 양쪽의 피연산자 모두 참으로 평가되는 경우에만 그 결과가 참이 된다.

연산자 ||에서처럼 최종 평가 결과가 참으로 된다고 해서 불린값 true가 반환된다는 것은 아니

다.

|| 연산자의 경우 좌측 피연산자의 평가가 참인 경우는 우측 피연산자를 평가하지 않고 바로

결과값을 반환하듯이 && 연산자의 경우는 좌측 피연산자의 평가가 거짓으로 되는 경우 우측

피연산자를 평가하지 않고 바로 좌측 값을 반환한다.

var result1 = null&&true;

var result2 = false&&"양파링";

Page 64: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

64 2장 _ 자바스크립트의 기본 문법

첫 번째 result1에는 null이 할당되고 두 번째 result2에는 false가 할당된다. 좌측이 거짓으로

평가됐으므로 좌측값을 그대로 반환하기 때문이다. 좌측값이 참으로 평가되면 우측 피연산자

값을 그대로 반환한다.

var result1 = true&&"양파링";

var resut2="스낵"&&"양파링";

두 경우 모두 &&의 결과값으로 “양파링”이 할당된다. 좌측값이 참으로 평가됐기 때문에 결국

우측값을 그대로 반환하기 때문이다.

부정 연산자(!)

다음은 부정 연산자 !를 알아보자.

var result=!피연산자

연산자 !는 피연산자를 오른쪽에 하나만 갖는다. 이 연산자는 오른쪽 피연산자를 평가한 결과

값의 반대값을 반환한다. 예를 들어 오른쪽 피연산자가 true로 평가되면 false를 반환한다.

var var1 = !(a == c)

var var2=!"양파링"

a와 c의 값이 같다면 !연산자는 false를 반환한다. 그렇다면 var2에 할당된 값은? false가 된다.

“양파링”은 값이 있는 문자열로서 true로 평가되고 그 반대값인 false가 반환되는 것이다.

논리 연산자에 대해 요약하면 다음과 같다. 논리 연산자 ||, &&의 경우에는 피연산자 평가값

과 연산자의 반환값이 다를 수 있다. 즉, 피연산자에 대한 평가는 참, 거짓으로 판정되지만 그

평가에 따라 좌측 또는 우측 피연산자값이 그대로 반환된다. 그러나 ! 연산자는 피연산자의 평

가값에 반대되는 불린값을 반환하기 때문에 객체가 반환될 수는 없고 항상 true/false만 반환

된다.

||, &&의 경우, 피연산자의 평가는 true/false로, 연산자의 반환값은 좌측 또는 우측 피연산자의 값

이 된다. !의 경우, 피연산자의 평가도 true/false로 하고 반환값도 true/false가 된다.

Page 65: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

2.3 실행 제어 65

2.3 실행 제어

이 절에서는 조건에 따라 실행 흐름이 변경되게 하고 싶거나 조건이 만족되는 동안 특정 구문

을 반복 실행하는 경우, 그리고 예외가 발생하는 경우 실행 흐름을 바꾸고 싶을 때 사용할 수

있는 자바스크립트의 실행 제어문을 알아보고 각 제어문의 특이사항을 살펴본다.

조건문

조건에 따라 프로그램의 실행 흐름을 제어하는 대표적인 방법으로 if 문과 switch 문이 있다.

그리고 간단한 조건문인 경우는 조건 연산자 ?를 사용할 수 있다.

if 문

if 문은 프로그램의 실행 흐름을 제어하는 기초적인 방법이다. 다음 예제를 보자.

var r='';

if(a > 2){

r = 'a는2보다크다';

}

else{

r='a는2보다작거나같다';

}

if(조건문)에 사용되는 조건문이 참을 반환하면 if 문의 코드 블록(code block)이 실행되고 그

렇지 않으면 else문의 코드 블록이 실행된다. 만약 여러 개의 조건을 평가해야 한다면 여러 개

의 if 문을 사용할 수 있다.

var r='';

if(a > 2){

r = 'a는2보다크다';

}

else if(a==2){

r='a는2이다"';

}

else{

r='a는2보다작다';

}

Page 66: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

66 2장 _ 자바스크립트의 기본 문법

조건 연산자(?)

자바스크립트의 ? 연산자는 if 문의 간단한 버전으로서 코드를 간결하게 만들어 준다.

조건식?식1:식2

조건식이 참으로 평가되면 식1이 실행되어 결과값이 반환되고 조건식이 거짓으로 평가되면 식

2가 실행되어 결과값이 반환된다. 식1, 식2는 값일 수도 있고 또는 실행문일 수도 있다. 다음은

값을 반환하는 예제다.

var r = (a > 2) ? 'a는2보다크다':'a는2보다작거나같다';

a>2이면 ‘a는 2보다 크다’ 문자열이 반환되고 그렇지 않으면 ‘a는 2보다 작거나 같다’ 문자열이

반환된다. 다음은 식1, 식2가 괄호( )와 콤마(,)를 이용해 여러 개의 명령문이 묶일 수도 있음을

보여준다.

var age = 16;

var sURL = age > 18 ? (

alert("Ok,계속진행할수있습니다."),

"continue.html"

) : (

alert("너무나이가어립니다.!"),

"stop.html"

);

location.assign(sURL);

조건식이 반환하는 불린값에 따라 실행할 괄호가 결정되고, 그런 다음 콤마로 분리된 마지막

값이 ? 연산자의 반환값이 된다.

switch문

너무 많은 else if를 사용하고 있다면 switch 문으로 대체해서 코드를 줄일 수 있다. 앞의 코드

를 switch 문으로 변경하면 다음과 같다.

var r='';

switch(a){

case a > 2 :

r = 'a는2보다크다';

Page 67: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

2.3 실행 제어 67

break;

case a==2 :

r='a는2이다"';

break;

default :

r='a는2보다작다';

break;

}

switch 다음에 오는 ( )안에는 주로 변수가 오지만 반환값을 제공하는 어떤 것도 올 수 있다.

switch는 중괄호 { }로 감싸져 있고 내부에 여러 개의 case가 올 수 있다.

case 다음에도 결과값을 반환하는 문장이 올 수 있는데(물론 하나의 변수만 오는 경우도 많

다), 이 결과값과 switch 문이 반환한 결과값이 같으면 콜론(:) 다음에 오는 코드가 실행된다.

case의 코드 블록은 중괄호로 묶여져 있지 않다. 대신 break 문을 사용해 코드 실행이 언제

끝날지 알려준다. 만약 break를 만나면 switch 문을 빠져나가지만 break 문이 없으면 다음

case 코드 블록을 실행한다. 이렇게 다음 case 블록까지 실행되는 것은 원하지 않는 것이 보통

이지만 다음 블록까지 실행하게 하는 경우도 가끔씩 발생한다.

마지막으로 default 코드 블록을 선택적으로 둘 수 있는데, 이 블록에는 조건을 판단하는 식이

없다. 앞에서 어떤 case도 참으로 판정되어 실행되지 않았다면 이 코드 블록이 실행된다.

조건 평가 규칙

원시 타입인 불린을 설명하면서 다음과 같은 조건 평가 규칙을 언급한 적이 있다.

비교 결과가 0, null, “”(빈 문자열), false, undefined, NaN 이외의 값으로 평가되면 항상 “참”으로 해석된다.

이것은 자바스크립트 코드의 줄 수를 줄이는 기법이기도 하지만 참, 거짓을 판단하는 규칙을

알지 못하면 약간 당황스러울 수 있다..

var obj; // undefined

if(obj != null){ //실행되지않음}

if(obj){ //실행되지않음}

Page 68: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

68 2장 _ 자바스크립트의 기본 문법

첫 번째 if 문의 조건식인 obj !=null은 undefined != null로 해석되기에 거짓을 반환한다.

“undefined과 null” 절에서 undefined == null은 참을 반환한다고 했다. 따라서 코드 블록

은 실행되지 않는다. 두 번째 if문의 조건식도 obj가 undefined인 관계로 거짓을 반환하고 따

라서 코드 블록이 실행되지 않는다.

앞에서 사용한 obj가 선언되지 않은 상태에서 비교를 하면 에러가 난다. 앞의 코드에서처럼

obj를 선언했지만 값을 할당하지 않은 경우에는 undefined로 초기화되어 비교 표현에 사용되

더라도 에러가 발생하지 않는다.

다음과 같은 상황을 생각해보자. 어떤 함수에서 인자를 받는데, 그 인자는 배열을 받기로 돼 있

다. 그래서 함수 내부에서는 그 인자에 아무 값도 할당하지 않은 채 호출하는 경우를 대비해서

그 인자에 빈 배열을 할당하는 코드를 구현해야 한다고 하자. 이 경우 다음과 같은 코드로 해결

할 수 있다.

//func정의

function func(a){

a= a||[];

if(a.length == 0){

}else{

}

}

//함수호출

func();

func( )를 호출할 때 위 예제처럼 인자 없이 호출하면 a는 undefined으로 되어 ||의 좌측은

false로 평가될 것이고 따라서 우측 표현이 실행된다. [ ]은 빈 배열 객체를 만드는 배열 리터럴

표현이다. 빈 배열 객체는 true로 평가되고, 그래서 빈 배열 객체가 || 연산 결과로 반환되어 a

에는 빈 배열 객체가 할당된다.

Page 69: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

2.3 실행 제어 69

반복문

반복문도 다른 언어를 익혔다면 그렇게 어렵지 않은 구문이다. 자바스크립트에도 for, for/in,

while, do/while과 같이 기본적으로 반복적으로 작업을 해야 하는 경우에 사용할 수 있는 구

문이 있다. 특이 사항 몇 가지만 정리하겠다.

for 문

for 문을 사용하는 문법은 아래와 같다.

for(변수초기화;반복여부테스트;변수값증가){

실행코드블럭

}

‘변수 초기화’ 부분이 한 번만 실행된다는 것은 다른 언어와 동일하다. 그런데 다른 점이 있다.

for(var i=0; i< 10; i++){

실행코드블럭

}

변수 i는 for 문 안에서만 사용할 수 있을까, 밖에서도 사용할 수 있을까? 나중에 함수를 배우

면서 변수의 영역은 함수 단위로 결정된다는 것을 배울 것이다. 이것은 다른 언어와의 중요한

차이점이다. 이로 인해 변수 i는 for 문 밖에서도 사용할 수 있게 된다.

자바스크립트의 변수 스코프는 중괄호({ })로 결정되는 것이 아니라 함수 단위로 결정된다.

이해를 돕기 위해 다음 코드를 보자.

function f(count){

alert(i); undefined반환

for(var i=0;i<count;i++){

};

return i;

}

f(100); 100반환

Page 70: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

70 2장 _ 자바스크립트의 기본 문법

파싱 단계에서 함수 내에 선언된 변수가 함께 정의된다. 그리고 변수를 검색할 때 { } 단위로 찾

는 것이 아니라 함수 단위로 찾는다. 위 코드를 파싱할 때 함수 f와 f 내부에서 선언된 변수 i가

정의된다. 이때 i는 undefined로 초기화된다. 변수 i가 유효한 영역은 for 문의 { } 코드 블록이

아니라 함수 f 내부의 전체 영역이다.

위 코드가 파싱을 거치고 나서 f(100)가 실행되면 f 내부에서 먼저 alert(i)가 호출되는데, 이때

“undefined”가 출력된다. alert(a)처럼 정의되지 않은 변수 a를 출력하면 “ReferenceError: a

is not defined” 같은 예외가 발생한다. 그다음 for 문을 통해 i는 100으로 증가되고 마지막으

로 return 문을 통해 100이 반환된다.

alert(i)와 f(100)의 반환값이 잘 이해되지 않는다면 두 가지를 상기하길 바란다. 바로 자바스크

립트 프로그램은 파싱 단계와 실행 단계를 거친다는 것과 파싱 단계에서 함수 단위로 변수가

정의된다는 것이다.

자바스크립트 프로그램은 파싱 단계와 실행 단계를 거친다. 파싱 단계에서 함수 단위로 변수가 정의된다.

만약 앞의 for 문에서 변수 i를 선언할 때 var를 생략하면 어떻게 될까?

function f(count){

for(i=0;i<count;i++){};

return i;

}

f(100); 100반환

i; 100반환

이제는 함수 외부에서도 i에 접근할 수 있게 된다. var 없이 선언된 변수는 전역 변수로 정의되

기 때문이다.

‘변수값 증가’ 부분에 올 수 있는 식은 i++만이 아니다. 다음과 같은 문장이 올 수도 있다.

for(i=0; i < a.length; a[i++]=0);//배열a의초기화

Page 71: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

2.3 실행 제어 71

이 for 문의 ‘실행코드블록’은 없다. 단지 for 문만 존재한다. 그래도 실행한 내용이 있다. ‘변수

값 증가’ 부분에서 배열 a[i]에 0을 할당하고 i를 1만큼 증가시킨다. 즉, a[0]~a[10]까지 0으로

초기화하는 작업을 하는 것이다.

for/in 문

for/in 문의 문법은 다음과 같다.

for(변수in객체){

실행코드블럭

}

구문에 있는 ‘변수’에는 var를 이용한 변수 선언이 들어갈 수 있다. 구문의 ‘객체’에는 객체 또는

배열이 올 수 있다. 먼저 객체가 오는 경우를 보자.

var myObject = { p1 : 'a', p2:'b'}; // myObject객체정의

var result='\n';

for (var prop in myObject) {

result+='속성명:'+prop+',값:'+myObject[prop] + '\n';

}

result ;

"

속성명:p1,값:a

속성명:p2,값:b

"반환

첫 번째 줄은 속성 p1, p2를 포함한 객체 myObject를 정의하는 코드다. 그런 다음 for/in 문

을 통해 myObject 객체의 속성에 접근하고 있다.

다음으로 myObject[prop]라고 돼 있는 부분을 보면 객체의 속성값에 접근하는 데 꺾쇠 괄호

([ ])를 이용한다. 흔히 알고 있는 객체 접근 연산자는 도트(.)다. 그러나 꺾쇠 괄호로도 접근할

수 있다는 것은 객체의 “멤버 관리 구조”를 읽고 나면 어렵지 않게 이해할 수 있다.

한 가지 언급할 것은 for/in 문으로는 사용자가 정의한 속성에만 접급할 수 있다는 것이다.

Object 객체에 원래 정의돼 있는 속성에는 접근할 수 없다. 이에 대해서는 객체의 멤버에 접근

하는 방법을 설명하면서 다시 언급한다.

Page 72: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

72 2장 _ 자바스크립트의 기본 문법

for/in 문은 다음처럼 배열 요소를 순환할 때 사용할 수도 있다.

var a = ['a', 'b'];//배열객체정의

var result = '\n';

for (var i in a) {

result+='인덱스:'+i+',요소값:'+a[i] + '\n';

}

result ;

"

인덱스:0,요소값:a

인덱스:1,요소값:b

"반환

배열 객체가 in 뒤에 오면 배열 요소의 인덱스 값이 변수 i에 할당된다. 이 인덱스값을 이용해

a[i]과 같은 식으로 배열 요소에 접근할 수 있다. 이제 다음 코드를 보자.

var o = {p1:1, p2:2};

var ar = [];

var i = 0;

for(ar[i++] in o);

ar; ??

위 for 문은 객체 o의 속성명을 배열 ar에 할당하는 일을 한다. 배열 ar은 결국 다음과 같이 할

당돼 있다.

["p1", "p2"]

for/in 문은 객체의 “멤버 관리 구조”에서 다시 설명하겠다.

while, do/while

while과 do/while에서는 특이한 점은 없다. 여기서는 간단히 문법만 소개한다.

var i = 0;

while (i < 10) {

i++;

}

Page 73: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

2.3 실행 제어 73

흔히 사용되지는 않지만 do/while 문을 이용할 수도 있다.

var i = 0;

do {

i++;

} while (i < 10) ;

while 문은 조건식이 먼저 나온다. 그래서 조건식에 따라서는 실행문이 한 번도 실행되지 않을

수 있다. 그러나 do/while 문은 조건식이 뒤에 나오고 따라서 실행문은 무조건 한 번 이상 실

행된다. 그리고 do/while은 세미콜론(;)으로 끝난다. while 문처럼 중괄호를 사용하면 코드가

언제 끝날지 알 수 있지만 do 문은 조건식으로 끝나기 때문에 세미콜론(;)을 사용해 코드의 끝

을 알려줘야 하기 때문이다.

예외 처리

try/catch/finally 문

다른 프로그래밍 언어에서처럼 자바스크립트에서도 프로그램에서 예외가 발생하는 경우 try/

catch 문을 사용해 예외를 처리하도록 지원한다.

try{

//실행코드를이곳에둔다.

}

catch(err){

//예외를이곳에서처리한다.

}

finally{

// try블록에서예외가발생하든발생하지않든항상실행되는코드를이곳에둔다.

}

try 코드 블록 내부에서 예외가 발생하면 언제든지 catch 문의 코드가 호출된다. 그리고

finally 블록의 코드는 try 블록에서 예외가 발생하든 발생하지 않든 항상 실행된다. try 블록에

서 return 문이 사용되더라도 finally 코드 블록은 반드시 실행된다.

catch 문과 finally 문이 반드시 있어야 하는 것은 아니다. 그래서 try/finally처럼 catch 문을

없애고 사용할 수도 있고 try/catch처럼 finally 없이도 사용할 수 있다.

Page 74: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

74 2장 _ 자바스크립트의 기본 문법

Error 객체

catch 블록이 호출될 때는 try 블록에서 발생한 예외에 대한 정보를 가지고 있는 Error 객체를

만들어 인자로 넘겨준다. 그러한 Error 예외 객체에 대한 정보는 다음과 같은 멤버를 갖는다.

멤버 설명

message 사람이 읽을 수 있는 있는 예외에 대한 상세 내용을 담고 있다.

name 예외 타입을 나타내는 문자열을 가지고 있다. name 값은 생성자(예외 타입)의 이름과 동일한 문자열을 반환한

다. Error 객체의 name은 “Error”를 반환한다.

예외 객체의 최상위 부모는 Error인데, 그것을 상속받는 모든 예외 객체는 이 속성을 상속해 그 생성자와 동

일한 이름의 문자열을 name을 통해 반환한다. 예를 들어, Error 자식 객체로는 EvalError, SyntaxError,

URIError, TypeError 등이 있는데, 그것들의 name 속성은 각각 “EvalError”, “SyntaxError”, “URIError”, “TypeError”를 반환한다.

Error의 자식 객체에 대해서는 다음 웹 페이지를 참고한다.

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error

toString 표준에서는 Error 객체에 대한 toString 메서드를 정의하고 있지만 스크립트 언어에서 반드시 구현할 필요는

없다. 예외에 대한 정보를 알고 싶다면 message, name을 참고한다.

throw 문

때로는 특정 조건이 만족되면 코드에서 직접 예외를 발생시키고 싶은 경우도 있다. 이런 경우

throw를 사용해서 다음처럼 예외를 발생시킬 수 있다.

throw예외객체

“예외객체” 자리에는 Error 또는 그 자식 객체가 올 수도 있지만 다음 코드처럼 예외를 나타내

는 문자열 또는 예외 코드를 나타내는 숫자가 올 수도 있다.

try{

//코드를이곳에둔다.

if(/*예외조건이만족되면*/){

throw new Error("예외가발생했습니다.");

throw"예외가발생했습니다.";

throw 4;

}

}

Page 75: 자바스크립트 객체지향 프로그래밍 : jQuery 구조 분석까지

2.3 실행 제어 75

catch(e){

//이곳에서예외정보에접근해예외를처리할수있다.

var m = e.message;

}

throw로 전달된 예외에 대한 내용은 위 코드의 catch 문에서처럼 message 속성을 통해 접근

할 수 있다.