2014-10-19 <Java Script for Web Developer> 1~6 요약본

 
1장. 자바스크립트란 무엇인가
1995년 처음 등장할 때 주요 목적은 서버 언어에서 담당하던 입력 유효성을 검사하기 위해서였다.
자바스크립트는 완전히 익히려면 자바스크립트의 성격과 역사, 한계에 대해 이해해야 한다.
1.1 간추린 역사
넷스케이프의 브랜든 아이흐가 처음엔 Mocha, 나중에 LiveScript라고 불린 스크립트 언어를 개발했는데 넷스케이프 내비게이터 2에서 브라우저와 서버(서버쪽은 LiveWire) 모두에서 사용하려는 것이었으며, 출시하기 직전 자바의 인기에 편승하기 위해 자바스크립트로 이름을 바꾸었다.
IE 3에선 저작권 문제를 피하기 위해 JScript라고 이름지었다. 이는 자바스크립트가 하나의 언어로 본격적으로 개발되기 시작한 의미 있는 날이다.
1997년 자바스크립트 1.1이 ECMA에 제안되었다. ECMA는 TC39 위원회에서 “문법과 의미를 표준화하여 일반적인 목적에 쓸 수 있고 플랫폼을 가리지 않으며 제조사에 중립인 스크립트 언어”를 만들기로 했으며, 1998년 ISO와 IEC에서도 ECMAScript를 표준(ISO/IEC-16262)으로 받아들였다.
1.2 자바스크립트 구현
자바스크립트 구현은 다음 세 가지로 나뉜다.
  • 코어 (ECMAScript)
  • 문서 객체 모델 (DOM:Document Object Model)
  • 브라우저 객체 모델 (BOM:Browser Object Model)
1.2.1 ECMAScript
ECMAScript ‘판’
ECMA-262의 최근판은 2009년에 만들어진 5판이며, 6판은 현재 2014년 12월 예정이다.
ECMA-262 3판이야말로 표준에 대한 첫 번째 진짜 업데이트이며, 진정한 프로그래밍 언어로 간주하는 이유다. ECMAScript 3.1이 ECMA-262 5판이라는 이름으로 2009년 12월 3일 공식 발표되었다.
웹 브라우저의 ECMAScript 지원
넷스케이프 내비게이터 4.06의 자바스크립트 1.3 버전이 ECMA-262 초판과 완전히 호환되었으며, 2008년부터 주요 웹 브라우저 모두 ECMA-262 3판을 준수하였다.
IE 8은 5판을 구현한 최초의 브라우저였으며 IE 9은 5판을 완전히 지원한다. 곧이어 파이어폭스 4도.
1.2.2 문서 객체 모델(DOM)
DOM은 XML을 HTML에서 사용할 수 있도록 확장한 API이며, 전체 페이지를 노드의 계층 구조로 변환한다. HTML(XML) 페이지의 부분을 데이터를 포함하는 다양한 타입의 트리 노드로 만들고 이를 통해 문서의 콘텐츠와 구조를 자유롭게 수정할 수 있다.
DOM이 필요한 이유
브라우저별로 다른 DHTML을 지원하면서 개발자들은 새로고침 없이 콘텐츠의 모양을 바꿀 수 있게 되었으나 브라우저 별로 HTML 페이지를 만들어야 하는 재앙이 발생했다. W3C에서 DOM 관련 작업을 시작했고 레벨 1,2,3가 차례대로 나왔다. 레벨 0는 W3C 작업 이전에 IE 4.0과 넷스케이프 내비게이터 4.0이 지원했던 DHTML을 말한다.
1.2.3 브라우저 객체 모델(BOM)
브라우저 창에 접근하고 조작할 수 있게 하는 인터페이스이며, 브라우저에 표시된 페이지와는 별개의 컨텍스트에서 브라우저와 상호작용할 수 있다.
표준이 없어 자주 문제를 일으켰으나, HTML5는 BOM을 공식 명세의 일부로 표준화하고 있어 개선되고 있다.
1.3 자바스크립트 버전
넷스케이프 소스코드가 모질라 프로젝트로 오픈소스로 공개될 때 자바스크립트 버전은 1.3이었다.
1.4 요약
자바스크립트는 웹페이지와 상호작용하도록 디자인된 스크립트 언어이며, 핵심 기능을 담당하는 ECMAScript(ECMA-262에서 정의), 웹 페이지 콘텐츠를 조작하는 DOM, 브라우저와 상호작용하는 BOM으로 구현된다.
주요 웹 브라우저들의 ECMAScript 3에 대한 지원은 일반적으로 좋은 편이며 ECMAScript 5에 대한 지원은 나아지고 있지만, DOM 지원은 편차가 심하다. BOM은 최근에야 HTML5에서 표준화되고 있으므로 일부 외에는 각기 다르다.
요약자 후기
관련 글들
 
 
2장. HTML 속의 자바스크립트
2.1 <script> 요소
자바스크립트를 HTML 페이지에 삽입하는 일차적인 방법이며, async, charset, defer, language, src, type의 여섯가지 속성이 있다. 현재 language는 페기되었고, charset 값은 무시된다. type 속성은 아직 습관적으로, 또는 브라우저 호환성을 위해 “text/javascript” 라 표기하곤 하나, 기본값이라서 생략 가능하다.
<script> 요소 안의 인라인 자바 스크립트 코드는 위에서부터 차례로 해석되며 코드 전체를 해석하기 전에는 페이지의 나머지 콘텐츠를 불러오지도 않고 표시하지도 않는다.
인라인 자바스크립트 코드에서 문자열 “”는“/” 문자를 \로 이스케이프해야 한다.
자바스크립트를 외부 파일에서 불러오려면 파일의 URL을 속성값으로 src 속성을 사용한다. 외부 파일의 코드를 내려받고 해석하는 동안 페이지 처리가 멈춘다.
<script type="text/javascript" src="example.js"></script>
중요<script>와 </script> 태그 사이에 스크립트 코드가 있고 src 속성도 사용했다면 브라우저는 스크립트 파일을 내려받아 실행하며 인라인 코드는 무시합니다.
신뢰할 수 있는 외부 도메인의 코드를 마치 페이지의 원래 일부였던 것처럼 불러와서 해석할 수 있다.
<script type="text/javascript" src="http://www.somewhere.com/afile.js">; </script>
2.1.1 태그 위치
전통적으로 <script> 요소는 외부 파일에 참조를 한곳에 관리하기 위해 페이지의 <head> 요소 안에 쓰는 것이 일반적이었다. 그러나, 최신 웹 앱에선 페이지 렌더링 시간의 지연을 막기 위해 <body> 요소 안에, 페이지 콘텐츠 마지막에 -</body> 태그 바로 앞에 - 쓴다.
2.1.2 스크립트 처리 지연(defer 속성)
defer 속성을 설정하면 브라우저는 즉시 코드를 내려받지만 실행은 페이지 전체를 파싱한 후에 한다. 그러나, 지연시킨 스크립트가 항상 순서대로 실행되지는 않으므로 <script> 요소를 하나만 쓰는 것이 최선이다. 그러나, 여러 브라우저 지원 문제 때문에 스크립트는 페이지 맨 마지막에 놓는 것이 최상이다.
2.1.3 비동기 스크립트(async 속성)
스크립트를 모두 내려받을 때까지 기다릴 필요없이 페이지 렌더링을 시작해도 좋으며, 앞선 스크립트 파일을 기다리지 않고 위의 스크립트 파일을 받아도 좋다고 명시하는 것이다. 스크립트가 순서대로 실행된다는 보장이 없어 여러 스크립트 파일 사이에 의존성이 있으면 안되며, DOM을 조작하는 스크립트는 비동기적으로 불러오지 않는 것이 좋다.
2.1.4 XHTML에서 바뀐 점
XHTML에서는 < 기호 다음 공백문자가 있으면 문법 에러가 발생하는데, <를 HTML 엔티티 &lt;로 변경하거나, CDATA 섹션으로 감싸줄 수 있다. 브라우저가 CDATA 섹션을 지원하지 않으면 CDATA 마크업 앞에 자바스크립트 주석 기호를 써야 한다.
2.2 인라인 코드와 외부 파일(src 속성)
외부 파일을 쓸 때 이점.
  • 관리가 쉽다.
  • 캐싱으로 페이지 불러오는 시간이 짧아진다.
  • 외부 파일 불러오는 문법이 HTML과 XHTML 모두 똑같으므로, 위의 편법을 쓰지 않아도 된다.
2.3 문서 모드
IE 5.5는 쿽스와 표준의 두 가지 문서모드 개념을 처음 도입했다. 두 모드의 주요 차이는 콘텐츠 렌더링과 관련된 것이지만 자바스크립트에도 영향이 있다. 다른 브라우저 들도 이를 도입함에 따라 '거의 표준 모드'라는 엄격하지 않은 표준 모드가 등장했다. 이미지 주변의 공백과 테이블 이미지 등에서 차이가 크다.
쿼크 모드는 브라우저 사이의 일관성을 전혀 기대할 수 없으므로 독타입을 이용하여 표준 모드로 사용한다. 표준 모드와 '거의 표준' 모드는 차이를 느낄 수 없기 때문에 일반적으로 '표준 모드'라는 용어는 쿽스 모드를 제외한 둘 모두를 말한다.
2.4 <noscript> 요소
<noscript>는 브라우저가 자바스크립트를 지원하지 않거나 지원이 꺼져 있을 때 대체 콘텐츠를 제공하며<script> 요소를 제외한 모든 HTML 요소를 사용할 수 있다. 브라우저에서 스크립트를 사용할 수 있을 때는 <noscript> 요소의 콘텐츠는 결코 표시되지 않습니다.
 
 
3장. 언어의 기초
3.1 문법
대소문자 구분
변수, 함수 이름, 연산자 모두 대소문자를 구분한다.
식별자(Identifiers)
'식별자'란 변수, 함수, 프로퍼티, 함수 매개변수의 이름이다. 식별자는 한 개 이상의 문자로 표기하며, 첫 번째 문자는 반드시 글자나 밑줄(_), 달러기호($) 중 하나이다.
ECMAScript는 관습적으로 카멜 케이스로 쓴다. 카멜 케이스란 첫번째글자는 소문자로 쓰고 단어가 바뀔 때는 바뀐 단어의 첫 글자를 대문자로 쓰는 표기법이다. 반드시 써야하는 것은 아니지만 ECMAScript 내장 함수와 객체가 카멜 케이스로 표기되어 있어서 따르길 권한다.
  • 키워드와 예약어 및 true, false, null은 식별자로 사용할 수 없다.
주석(comments)
ECMAScript는 한 줄 주석과 블록 주석 모두 C언어 스타일로 표기한다.
// 한줄 주석
/*
  • 블록 주석은 /*로 시작하고,
  • 그 반대 */로 끝난다. */
두번 째와 세 번째 줄에있는 *는 가독성을 위해 추가한 것이며 기업 애플리케이션에서 선호한다.
스트릭트 모드(Strict Mode)
ECMAScript 5에서 도입하였는데, 안전하지 않는 동작에서는 에러를 반환하도록 한다.
전체 스크립트에 스트릭트 모드를 적용하려면 다음 문장을 스크립트 최상단에 추가한다.
"use strict";
함수 단 하나만 적용하려면 다음 선언(pragma)을 함수 본문 맨 앞에 추가한다.
function doSomething(){
    "use strict";
    // 함수 본문
}
IE 10+, 파이어폭스 4+, 사파리 5.1+, 오페자 12+, 크롬에서 지원한다.
문장(Statements)
ECMAScript에서 각 문장은 세미콜론으로 종료한다. 꼭 써야하는 것은 아니지만 여분의 공백 제거, 압축 시 문법 에러, 성능 향상 등의 이유로 세미콜론으로 종료해라.
C 언어 스타일 문법을 써서 여러 문장을 코드 블록으로 합칠 수 있다. {로 시작하여 }로 끝난다. 실행한는 문장이 하나뿐이더라도 에러의 원인이 되기도 하므로 코드블록을 써라.
3.2 키워드와 예약어
ECMAScript의 키워드와 예약어는 식별자 이름이나 프로퍼티 이름으로 사용하지 마라.
3.3 변수
ECMAScript는 느슨한 변수타입을 사용하므로, 변수에 어떠한 타입의 데이터라도 저장할 수 있다. 모든 변수는 단순히 값에 대한 이름 붙은 플레이스홀더일 뿐이다.
변수를 정의 할 때에는 var 연산자 다음에 변수 이름을 쓴다. var는 키워드이며, 변수 이름은 식별자이다. 변수를 초기화하지 않으면 특별한 값 undefined 가 할당되며, 다음과 같이 변수 선언과 동시에 값을 할당할 수 있다.
var message = "h1";
var 연산자는 변수를 로컬 스코프에서 정의한다. 함수 안에서 var 키워드를 써서 변수를 정의하면 해당 변수는 함수를 종료하는 즉시 파괴된다.
var 연산자를 생략하면 변수를 전역으로 정의할 수 있으며, 함수를 호출하는 즉시 변수가 정의되며, 함수 외부에서도 이 변수에 접근할 수 있다. 그러나 이런 패턴은 피해라.
변수를 여러 개 선언하려면 쉼표로 구분하여 같은 문장에서 선언하고 초기화할 수 있다. 변수 사이에 줄바꿈과 들여쓰기로 읽기 쉽게 한다:
var message = "h1",
    found = false,
    age = 29;
3.4 데이터 타입
ECMAScript에는 Undefined, Null, Boolean, 숫자, 문자열의 다섯가지 기본적인 데이터 타입(원시 primitive 데이터 타입)이 있으며, 이름-값 쌍의 순서없는 목록 즉, 객체라는 복잡한 데이터 타입도 있다. 이 여섯 가지의 데이터 타입은 동적이어서 한 가지 데이터 타입이 여러 특성을 가질 수 있다.
typeof 연산자(Operator)
typeof 연산자를 통해 데이터 타입을 알 수 있으며, 값(변수)에 typeof 연산자를 적용하면 다음 문자열 중 하나를 반환한다.
  • 정의되지 않은 변수 : "undefined"
  • 불리언 : "boolean"
  • 문자열 : "string"
  • 숫자 : "number"
  • 함수를 제외한 객체 또는 null : "object"
  • 함수 : "function"
undefined 타입
기본적으로 초기화하지 않는 변수에는 항상 undefined 값이 할당된다. 그러나, 변수를 항상 초기화하는 습관을 갖으면 typeof에서 undefined를 반환했을 때 해당 변수가 초기화되지 않은 것인지, 정의되지 않은 것인지 바로 알 수 있다.
Null 타입
Null 타입의 값은 특별한 값인 null이다. null은 빈 객체를 가리키는 포인터이므로 null에 typeof를 호출하면 object를 반환하며, 객체를 사용해야 하지만 해당 객체를 이용할 수 없을 때 null을 사용하여 해당 변수가 객체를 자리키는지 명시적으로 확인할 수 있다.
불리언 타입
불리언 타입은 ECMAScript 에서 가장 많이 쓰이는 데이터 타입 중 하나이며 true와 false 두 가지 리터럴 값만 가진다. 숫자 타입과 달라, ture는 1이 아니며, false는 0이 아니다.
Boolean() 함수는 어떤 타입의 데이터에서도 호출할 수 있고 항상 불리언 값을 반환한다.
데이터 타입
true 값
false 값
불리언
ture
false
문자열
비어 있지 않은 문자열 모두
" "(빈 문자열)
숫자
0이 아닌 모든 숫자, 무한대 포함
0, NaN
객체
모든 객체
null
Undefined
해당없음
undefined
if 문 같은 제어문은 타입을 자동으로 불리언으로 바꾸므로 위 표의 변환 규칙을 반드시 이해해야한다.
숫자 타입
기본적인 숫자 리터럴 형식은 10진법이다. 정수는 8진수 리터럴, 16진수 리터럴도 가능하지만 실제 계산시에는 항상 10진수로 변환하여 계산한다.
부동소수점 숫자
부등소수점 숫자를 표현하려면 반드시 소수점이 있어야 하며, 소수점 뒤에 숫자를 쓴다. .1도 가능하지만 권장하지 않는다.
부동소수점 숫자는 정수보다 메모리를 두 배로 소모하므로 소수점 뒤에 숫자가 없다면 정수로 변환된다.
대단히 크거나 작은 부동소수점 숫자를 표현할 때는 'e- 표기법(지수 표기법)'을 쓴다. 기본적으로 소수점 뒤에 0이 6개 이상 있는 모든 부동소수점 숫자를 지수 표기법으로 변환한다.
숫자 범위
메모리 제한 때문에 모든 숫자를 표현할 수 없다. ECMAScript로 표현할 수 있는 최소값은 브라우저마다 다르지만 보통 5e-324이다. 최대값은 보통 1.7976931348623157e+308이다. 이 범위를 벗어나면 자동으로 (-)Infinity로 변환된다.
NaN(Not a Number)
숫자를 반환할 것으로 의도한 조작이 실패했을 때 반환하는 특별한 값이며, 에러를 반환하는 것은 아니다.
NaN이 포함된 모든 조작은 항상 NaN을 반환하며, 심지어 NaN끼리도 서로 일치하지 않는다. isNaN() 함수는 해당 값이 '숫자가 아닌 값'인지 검사한다. 문자열 "10"이나 불리언 값은 숫자도 바꿀 수 있다.
숫자 변환
숫자가 아닌 값을 바꾸는 함수는 어떤 데이터 타입에도 쓸 수 있는 Number(), 문자열을 숫자로 바꾸는 parseInt()와 parseFlaot() 함수 세 가지이다.
Number()함수로 문자열을 숫자로 바꿀 때는 여러 규칙을 기억해야 한다.
정수 형태의 문자열을 숫자로 바꿀 때 보통 parseInt()을 사용하며, var num = parseInt("10", 10)의 형태로 사용한다.
parseFlaot() 함수는 두 번째 소수점과 같은 잘못된 부동소수점 숫자를 만날 때까지 파싱을 계속하여, 그 이후 문자열은 무시한다. 리딩제로는 항상 무시한다. 또한, 항상 10진수 기준으로 파싱하기 때문에 16진수는 항상 0을 반환한다.
문자열 타입
문자열 데이터 타입은 16비트 유니코드 문자의 연속이다. 문자열은 큰따옴표나 작은따옴표로 감싸서 표현한다. PHP에서는 큰따옴표와 작은따옴표를 다르게 해석하지만 ECMAScript는 완전히 똑같게 해석한다. 그러나 짝은 맞아야 한다.
문자 리터럴
문자열의 성질
ECMAScript에서 문자열은 불변(immutable)이다. 즉, 문자열이 만들어지면 그 값을 바꿀 수 없다. 변수에 저장된 문자열을 바꾸려면 기존의 문자열을 파괴하고 다음과 같이 해당 변수에 새 문자열을 채워야 한다.
var lang = "Java";
lang = lang + "Script";
문자열로 변환
값을 문자열로 바꾸는 방법은 거의 모든 값에 존재하는 toString() 메서드를 사용하는 것과 호출할 값이 null이나 undefined일 가능성이 있을 경우 String() 함수를 사용하는 두 가지 방법이 있다.
객체 타입
객체는 데이터와 기능의 집합이다. 객체는 new 연산자 다음에 새로 만들 객체 타입의 이름을 써서 만든다.
var o = new Object();
Object 타입은 이 타입에서 파생하는 모든 객체의 원형이기 때문에 Object 타입의 인스턴스는 Object 타입의 프로퍼티와 메서드를 전부 상속한다.
3.5 연산자(OPERATORS)
단항 연산자(Unary Operators)
단 하나의 값에만 적용되는 연산자이며, 가장 단순한 연산자이다.
증감 연산자
C 언어에서 차용한 것이며, 피연산자의 앞에 쓸 수도 있고 뒤에 쓸 수도 있다. ++를 피연산자 앞에 쓰면 피연산자에 1을 더하며, --를 쓰면 피연산자에서 1을 뺀다.
증감 연산자를 변수 앞에 쓰면 변수의 값을 바꾼 다음 문장을 계산한다. 변수 뒤에 쓰면 문장을 계산한 다음에 적용되는 중요한 차이가 있다.
단항 플러스와 단항 마이너스
비트 연산자(Bitwise Operators)
가이드에서 언급한 대로 건너뜀
불리언 연산자
불리언 연산자에는 NOT과 AND, OR 세가지가 있다.
논리 NOT
논리 NOT 연산자는 느낌표!로 표시하며 모든 값에 적용할 수 있다. 피연사자를 불리언 값으로 변환한 다음 그 결과를 부정하며, 다음과 같이 동작한다.
피연산자
반환값
객체
false
빈 문자열
true
비어있지 않은 문자열
false
숫자 0
true
0이 아닌 숫자(Infnity 포함)
false
null
true
NaN
true
undefined
true
논리 NOT 연산자를 연달아 두 개 쓰면 Boolean() 함수를 쓴 것과 같은 효과가 있다.
논리 AND
앰퍼샌드 2개&&로 나타내며 값 두 개에 적용한다. 피연산자가 불리언 값이 아니어도 사용할 수 있으며, 그 동작은 약간 복잡하다;;
논리 OR
파이프 두개||로 표현한다. 피연산자가 불리언 값이 아니라도 사용할 수 있으며, 그 동작은 약간 복잡하다;;
다음과 같이 그 행동을 이용해서 변수에 null이나 undefined가 저장되지 않게 할 수 있다:
var myObject = preferredObject || backupObject;
곱셈 관련 연산자(Multiplicative Operators)
곱셈, 나눗셈, 나머지의 세가지 곱셈 관련 연산자가 있다.
곱셈
아스테리스크*를 써서 나타내며 두 숫자를 곱하는 데 쓰인다.
나눗셈
슬래시/ 기호로 표현하며, 첫 번째 피연산자를 두 번째 피연산자로 나눈다.
나머지(Modulus)
퍼센트 기호%로 나타내며 나눗셈을 적용하고 나머지를 반환한다.
덧셈 관련 연산자
덧셈
피연산자 중 하나가 문자열이라면 다음 규칙을 따르며, 아래 예제와 같은 흔한 실수를 피해야 한다.
  • 피연산자가 모두 문자열이라면 두 번째 문자열을 첫 번째 문자열에 합한다.
  • 피연사자 중 하나가 문자열이라면 다른 피연산자를 문자열로 변환하고 두 문자열을 합친다.
var num1 = 5;
var num2 = 10;
var message = "The sum of 5 and 10 is " + num1 + num2;
alert(message);     // "The sum of 5 + 10 is 510"
이를 피하기 위해서는 (num1 + num2)와 같이 괄호로 감싸 괄호 안을 먼저 계산한 후에 그 결과를 문자열에 합쳐야 한다.
뺄셈
관계 연산자(Relational Operators)
관계 연산자에는 미만<과 초과>, 이하<=와 이상>= 연산자가 있다. 두 값을 비교하여 불리언 값을 반환한다.
피연산자 중 하나가 숫자라면 다른 피연산자를 숫자로 변환한 후 비교하며, 하나가 불리언이라면 숫자로 바꾼 후 비교한다.
피연산자가 모두 문자열이면 서로 대응하는 문자의 문자 코드를 비교하는데, 알파벳의 대문자 전체가 소문자의 문자 코드보다 작기 때문에 대소문자를 전부 통일한 다음 비교하는 등의 주의가 필요하다.
NaN과 비교는 항상 false를 반환한다.
동일 연산자(Equality Operators)
ECMAScript에서는 연산자를 두 벌로 분리해서 '동일' '비동일' 연산자는 비교 전에 타입을 변환하며, '일치' '불일치' 연산자는 타입 변환 없이 비교하는 것으로 정했다.
동일, 비동일(Equal and Not Equal)
동일 연산자는 ==로 표시하며 동일하면 true를 반환한다. 비동일 연산자는 !=로 나타내며 동일하지 않으면 true를 반환한다. 피연산자를 비교하기 전에 변환하며, 이를 종종 '타입 강제(type coercion)'라 부른다.
  • null과 undefined는 동일하며, 이 둘은 다른 값으로 변환하여 평가하지 않는다.
  • 피연산자 중 하나가 NaN이라면 동일 연산자는 false를, 비동일 연산자는 true를 반환한다. 피연산자가 모두 NaN이라도 동일 연산자는 항상 false를 반환한다. NaN은 NaN과 같지 않다.
  • 피연산자가 모두 객체라면 객체끼리 비교하는 것이 아니라 객체에 대한 참조를 비교한다.
일치, 불일치(Identically Equal and Not Identically Equal)
일치 연산자는 ===로 나타내며 피연산자의 타입을 변환하지 않아도 같을때에만 true를 반환한다. 불일치 연산자는 !==로 나타내며 피연산자의 타입을 변환하지 않는 상태에서 일치하지 않을 때에만 true를 반환한다.
null과 undefined는 비슷한 값이므로 null == undefined는 true를, null === undefined는 false를 반환한다.
동일/비동일 연산자보다는 일치/불일치 연산자를 써라!
3항 연산자(Conditional Operator)
variable = boolean_expression ? true_value : false_value;
boolean_expression이 true면 변수 variable에 true_value를 저장하며, false면 false_value가 저장된다.
var max = (num1 > num2) ? num1 : num2;
위 예제에서는 max에 num1과 num2 중 큰 값이 저장된다.
할당 연산자(Assignment Operators)
단순한 할당은 =로 나타내며 단순히 값을 변수에 할당한다. 다음과 같이 복합 할당을 적용하여 줄여 쓸 수 있으나, 성능이 좋아지는 것은 아니다.
num = num + 10;
num += 10;      // 복합 할당으로 위와 같다.
쉼표 연산자
쉼표(,) 를 사용해 여러문장을 한 문장으로 합칠 때 쓴다.
3.6 문장(STATEMENTS)
ECMA-262에는 몇가지 문장이 정의되어 있는데 이를 '제어문: flow-control statements'이라 부르기도 한다. ECMAScript 대부분이 문장을 통해 정의되며 일반적으로 키워드와 연결되어 있다.
if 문
if (condition) statement1 else statement2
대부분은 언어에서 가장 많이 쓰이는 제어문이며, 조건에 해당하는 것이 불리언 값이 아니면 Boolean() 함수를 호출하여 불리언 값으로 바꾼다. 실행 코드는 한 줄의 코드라도 코드 블록으로 사용하라. if문을 연이어 쓸 수도 있다.
do-while 문
do {
    statement
} while (expression);
do-while 문은 평가전 루프이며, 이는 루프의 종료 조건을 평가하기 전에 루프 본문을 실행한다는 뜻이다. 루프 본문을 적어도 한번은 실행한 후 빠져나가야 하는 상황에서 주로 사용한다.
while 문
while(expression) statement
while문은 평가 후 루프이며, 이는 루프 본문을 실행하기 전에 종료 조건을 평가한다는 뜻이다.
for 문
for (initialization; expression; post-loop-expression) statement
for 문은 평가후 루프인데, 루프에 들어가기 전에 변수를 초기화(initialization)할 수 있으며 루프 후 코드(post-loop-expression)도 지정할 수 있다. 조건 표현식이 true일 때만 실행하므로, while 문과 같이 루프 본문의 코드를 실행하지 않을 때도 있다. 루프 본문을 실행하면 루프 후 코드 역시 실행한다.
while 루프로 실행할 수 없는 일은 for 루프로도 불가능하다. for 루프는 단순히 루프 제어와 관련된 코드를 한곳에 모았을 뿐이다.
for 루프에서 반복을 결정하는 변수(i:iteration)를 반드시 for 루프의 변수 초기화 부분에서 var 키워드로 초기화해야 하는 건 아니다. for 루프 밖에서 초기화해도 된다. 또한, ECMAScript에는 블록 레벨 변수가 존재하지 않아 루프 안에서 변수를 선언하더라도 밖에서 이 변수에 접근할 수 있다.
옵션인 초기화, 조건 표현식, 루프 후 코드를 모두 생략하여 무한루프를 생성할 수도 있으며, 조건 표현식 하나만 명시하면 while 루프처럼 동작한다.
for-in 문
for (property in expression) statement
for-in 문은 엄격한 반복문이다. for-in 문은 객체의 프로퍼티를 나열하는데 사용한다.
문장 레이블
label: statement
문장에 레이블을 붙였다가 나중에 사용가능하며, 일반적으로 중첩된 루프에서 사용한다.
break 문과 continue 문
break 문과 continue 문을 통해 루프 내부의 코드 실행을 세밀히 조절할 수 있다. break 문은 즉시 루프에서 빠져나가 루프 다음 문장을 실행하는 반면, continue 문은 즉시 루프를 빠져나가지만 루프 실행은 지속된다.
break 문과 continue 문을 문자 레이블과 함께 사용하면 코드의 특정 위치로 이동할 수 있다.
루프는 전체적인 성능에 영향을 미치며, 개발자의 의도를 파악하기 어렵게 만들어 디버그나 유지 보수에도 문제가 생길 수 있으니 continue 문은 사용하지 마라.
with 문
with (expression) statement;
with 문은 코드의 스코프를 특정 객체에 고정한다. 원래 의도는 특정 객체를 코드에서 매우 자주 참조할 때 편리하자는 것이었다.
with 문 내부의 변수는 우선 지역 변수로 간주한다. 지역 변수에서 찾을 수 없다면 with 문과 함께 쓴 객체의 프로퍼티 중에서 같은 이름으로 검색하여, 해당 이름을 프로퍼티로 평가한다.
스트릭트 모드에서는 with 문을 금지하며 문법 에러로 간주한다. with 문은 성능에 악영향이 있으며 디버그도 힘들어, 배포할 최종 코드에 with 문을 쓰지 마라.
switch 문
switch (expression) {
    case value: statement
        break;
    case value: statement
        break;
    case value: statement
        break;
    case value: statement
        break;
    default: statement
}
if 문과 관련이 깊으며 C언어 기반의 문법과 매우 비슷하다. switch 문의 각 case는 '표현식이 value와 일치하면 statement를 실행하라'는 의미이다. break 키워드를 코드 실행을 멈추고 switch 문을 빠져나가라는 의미이며, 쓰지 않으면 다음 case를 계속 평가한다. default 키워드는 case 중 value로 평가되는 것이 없을 때 실행할 문장이다. 즉, else 문과 같은 구실을 한다.
case 문마다 break 문을 넣어서 다음 case까지 진행하지 않게 하라. 만약 다음 case 문까지 진행하기 해야 한다면, 주석(/* falls through */ 등)을 달아서 의도적으로 break 문을 생략했으며 실수가 아님을 분명히 한다.
ECMAScript의 switch 문은 모든 데이터 타입에서 동작하는 고유한 특징이 있어 문자열과 객체에서도 사용할 수 있으며, 값이 상수일 필요가 없으며 변수나 표현식도 쓸 수 있다.
switch 문은 일치 연산자(===)로 값을 비교하므로 타입 변환이 일어나지 않는다.
3.7 함수
함수는 문장을 캡슐화하여, 언제 어디서든 실행할 수 있게 하므로 모든 언어의 핵심이다. function 키워드로 정의하며 그 뒤에 매개변수와 함수 본문을 순서대로 쓴다.
function functionName(arg0, arg1, ... , argN) {
    statements
}
함수는 꼭 값을 반환하지 않아도 된다. 모든 함수는 return 문 뒤에 반환값을 써서 값을 반환할 수 있다. return 문 뒤의 코드는 결코 실행되지 않는다.
return 문 뒤에 반환값을 쓰지 않아도 되며, 이 때 함수는 return 문을 만나는 즉시 실행을 멈추고 undefined 값을 반환한다.
함수는 항상 값을 반환하거나 항상 반환하지 않게 만들어라. 즉, 반환에 일관성이 있어야 한다. 그렇지 않으면 디버그하기 어려울 수 있다.
스트릭트 모드에서의 함수 제한
  • 함수 이름과 매개변수 이름에 eval이나 arguments는 쓸 수 없다.
  • 서로 다른 매개변수에 결코 같은 이름을 쓸 수 없다.
매개변수의 이해
ECMAScript 함수는 매개변수 숫자를 따지지 않으며 데이터 타입도 체크하지 않는다.
함수는 arguments라는 객체를 하나 갖는데, 이 객체를 통해 매개변수의 값에 접근할 수 있다. arguments 객체는 각 매개변수를 대괄호 표기법, 첫 번째 매개변수는 arguments[0], 두 번째는 arguments[1] 형태로 접근하며 매개변수 개수를 length 프로퍼티를 통해 알 수 있다는 면에서 배열처럼 동작하기는 하지만 Array의 인스턴스는 아니다.
ECMAScript의 매개변수는 모두 값으로 넘겨야 한다. 매개변수를 참조 형식으로 전달할 수는 없다.
오버로딩 없음
ECMAScript에서는 같은 이름으로 함수를 여러 번 정의하면 마지막 함수가 해당 이름을 소유한다.
함수에 넘긴 매개변수의 타입과 숫자를 체크해서 그에 맞게 반응하는 방법으로 오버로딩을 흉내낼 수 있다.
 
 
4장. 변수와 스코프, 메모리
자바스크립트 변수는 느슨한 타입을 취하여, 변수의 이름만 그대로이고, 값과 데이타 타입은 스크립트 실행 중에도 바뀔 수 있다.
4.1 원시 값과 참조 값
ECMAScript의 변수는 원시 값과 참조 값(Primitive And Reference Values) 두가지 타입의 데이터를 저장할 수 있다.
원시 값은 단순한 데이터이며, Undefined, Null, 불리언, 숫자, 문자열이다. 변수에 저장된 실제 값을 조작하기 때문에 '값으로' 접근한다고 한다. 원시 값은 고정된 크기를 가지며 스택 메모리에 저장된다.
참조 값은 여러 값으로 구성되는 객체이자 메모리에 저장된 객체이며, 힙 메모리에 저장된다. 객체를 조작할 때는 객체 자체가 아닌 해당 객에 대한 '참조'를 조작하기 때문에 '참조로 접근한다'고 한다.
동적 프로퍼티
참조 값을 다룰 때는 언제든 프로퍼티와 메서드를 추가하거나 바꾸고 삭제할 수 있으며, 객체를 파괴하거나 프로퍼티를 제거하기 전까지는 접근할 수 있다. 원시 값에는 프로퍼티가 없으며, 참조 값만이 동적으로 프로퍼티를 추가할 수 있다.
값 복사
원시 값은 다른 변수로 복사할 때 저장된 값을 새로 생성한 다음 새로운 변수에 복사하여 두 변수를 완전히 분리한다. 참조 값을 변수에서 다른 변수로 복사하면, 힙(heap: 브라우저가 쓰는 메모리)에 저장된 객체를 가리키는 포인터 값을 복사하므로 두 변수는 정확히 같은 객체를 가리킨다. 따라서 한쪽을 조작하면 다른 쪽에도 반영된다.
매개변수 전달(Argument Passing)
ECMAScript의 함수 매개변수는 모두 값으로 전달된다. 원시 값이던 참조 값이던 함수 매개변수는 지역 변수에 복사되어 실행되며 함수 내에서만 동작하고 외부에 반영되지 않는다. 객체의 경우에도 외부 객체에 프로퍼티만 추가될 뿐이며, 생성된 지역 객체는 함수가 실행을 마치는 즉시 파괴된다. 함수 매개변수는 지역 변수와 다를 것이 없다고 생각하라.
타입 판별
typeof 연산자는 변수가 문자열이나 숫자, 불리언, undefined라면 정확한 타입을 알 수 있다. 값이 객체이거나 null이면 "object"를 반환한다.
instanceof 연산자는 변수가 주어진 참조 타입의 인스턴트일 때 true를 반환하기 때문에, 어떤 타입의 객체인지 판별할 때 도움이 된다. 원시 값은 항상 false를 반환다.
요약: typeof 연산자는 값의 원시 타입을 판별하며 instanceof 연산자는 값의 참조 타입을 판별한다.
4.2 실행 컨텍스트와 스코프
실행 컨텍스트(execution context:EC)는 짧게 '컨텍스트'라고 부르며, 비할 바 없이 중요한 개념이다. 변수나 함수의 실행 컨텍스트는 다른 데이터에 접근할 수 있는지, 어떻게 행동하는지를 규정한다. 각 실행 컨텍스트에는 변수 객체(variable object:VO)가 연결되어 있으며 해당 컨텍스트에서 정의된 모든 변수와 함수는 이 객체에 존재한다. 이 객체를 코드에서 접근할 수는 없지만 이면에서 데이터를 다룰 때 이 객체를 이용한다.
가장 바깥쪽에 존재하는 실행 컨텍스트는 전역 컨텍스트이다. 웹 브라우저에서는 이 컨텍스트를 windows라고 부르며, 전역 변수와 함수는 모두 window 객체의 프로퍼티 및 메서드로 생성도니다.실행 컨텍스트는 포함된 코드가 모두 실행될 때 파괴되는데, 이때 컨텍스트 내부에서 정의된 변수와 함수도 함께 파괴된다. 전역 컨텍스트는 애플리케이션이 종료될 때, 예를 들어 웹 페이지에서 나가거나 브라우저를 닫을 때까지 유지된다.
함수를 호출하면 자체의 실행 컨택스트가 생성된다. 코드 실행이 함수로 들어갈 때마다 함수의 컨텍스트가 컨텍스트 스택에 쌓인다. 함수 실행이 끝나면 해당 컨텍스트를 꺼내고 컨트롤을 이전 컨텍스트에 반환한다.
컨텍스트에서 코드를 실행하면 변수 객체에 '스코프 체인(scope chain)'이 만들어진다. 스코프 체인의 목적은 실행 컨텍스트가 접근할 수 잇는 모든 변수와 함수에 순서를 정의하는 것이다.스코프 체인의 앞쪽은 항상 코드가 실행되는 컨텍스트의 변수 객체이다. 컨텍스트가 함수라면 '활성화 객체(activation object)'를 변수 객체로 사용한다. 활성화 객체는 항상 arguments 변수 단 하나로 시작한다(이 변수는 전역 컨텍스트에는 존재하지 않는다). 변수 객체의 다음 순서는 부모 컨텍스트이며 그 다음에는 부모의 부모 컨텍스트이다. 이런 식으로 스코프 체인의 마지막인 전역 컨텍스트에 도달할 때까지 계속한다. 식별자를 찾을 때는 스코프 체인 순서를 따라가며 검색하며, 찾을 수 없다면 일반적으로 에러가 발생한다.
내부 컨텍스트는 스코프 체인을 통해 외부 컨텍스트 전체에 접근할 수 있지만 외부 컨텍스트는 내부 컨텍스트에 대해 전혀 알 수 없다.
스코프 체인 확장
Scope Chain Augmentation 실행 컨텍스트에는 전역 컨텍스트와 함수 컨텍스트 두 가지 타입만 있지만(eval()은 세 번째 타입이 있다) 스코프 체인을 확장할 수 있는 방법도 있다.
try-catch 문의 catch 블록과 with 문은 모두 스코프 체인 앞 부분에 임시로 변수 객체를 만들며 코드 실행이 끝나면 사라진다. with 문에서는 해당 객체가 스코프 체인에 추가되며 catch 문에서는 에러 객체를 선언하는 변수 객체가 생성된다.
자바스크립트에는 블록 레벨 스코프가 없다
No Block-Level Scopes 블록 레벨 스코프를 지원하는 언어에서는 for문의 초기화 부분에서 선언한 변수가 오직 for문의 컨텍스트 안에서만 존재한다. 그러나 자바스크립트에서는 for문에서 선언한 i변수가 루프 실행이 끝난 후에도 존재한다.
변수 선언
var를 사용해 선언한 변수는 자동으로 가까운 컨텍스트에 추가된다. 함수 내부에서는 함수의 로컬 컨텍스트가 가장 가까운 컨텍스트이며 with 문 내부에서는 함수 컨텍스트가 가장 가까운 컨텍스트이다. 변수를 선언하지 않은 채(함수 내부에서 var 키워드가 생략된 채) 초기화하면 해당 변수는 자동으로 전역 컨텍스트에 추가된다.(외부에서 접근할 수 있게 된다)
항상 변수를 선언한 다음 초기화하라. 스트릭트 모드에서는 변수를 선언하지 않고 초기화하려 하면 에러를 낸다.
식별자 검색
컨텍스트 안에서 식별자를 참조하려면 검색부터 해야 하고, 스코프 체인을 따라 검색을 계속하여 전역 컨텍스트의 변수 객체에 도달할 때까지 계속한다. 식별자를 찾지 못하면 정의되지 않은 것으로 판단한다.
이러한 검색 과정 때문에 식별자가 로컬 컨텍스트에 정의되어 있으면 부모 컨텍스트에 같은 이름의 식별자가 있다 해도 참조할 수 없다.
4.3 가비지 콜렉션
자바스크립트는 실행 환경에서 코드 실행 중에 메모리를 관리한다는 의미에서 가비지 콜렉션(garbage collection) 언어이다. 필요한 메모리를 자동으로 할당하고 더 이상 사용하지 않는 메모리는 자동으로 회수하므로 직접 메모리를 관리하지 않아도 된다.
더 이상 사용하지 않는 변수를 식별하는 기준은 브라우저마다 다르지만 보통 구 가지 방법을 채용한다.
표시하고 지우기(Mark-and-Sweep)
가장 널리 쓰인다.
참조 카운팅(Reference Counting)
널리 쓰이지는 않지만, 이 방식의 주안점은 각 값이 얼마나 참조되었는지 추적한다는 것이다.
참조 카운팅 방법은 넷스케이프 내비게이터 3.0에서 처음 사용되었으나 즉시 순환 참조라는 심각한 문제가 뱔견되었다. 버전 4.0에서 참조 카운팅 방식을 버렸다.
IE 8과 그 이전 버전에서는 BOM과 DOM의 객체들이 참조 카운 방식을 이용하는 C++의 COM 객체로 구현되었다. 이 경우 순환 참조 문제를 해결하려면 해당 객체들에 null을 할당하여 연결을 끊어야 한다. IE 9에서는 BOM과 DOM 객체를 진정한 자바스크립트 객체로 만들어 이 상황을 다소 완화했다.
성능
가비지 컬렉터는 주기적으로 실행되며 메모리 내에 할당된 변수가 많다면 상당한 비용이 드는 작업이므로 실행 타이밍이 중요하다. IE는 가비지 컬렉터를 할당 숫자 기준으로 너무 자주 실행하여 성능 문제를 일으키는 것으로 악명이 높다.
메모리 관리
일반적으로는 가비지 컬렉션 환경에서는 개발자가 메모리 관리를 신경쓰지 않아도 되지만, 웹 브라우저에서 사용할 수 있는 메모리는 일반적인 테스크톱 애플리케이션의 가용 메모리에 비해 매우 적다.
페이지 성능을 올리기 위해 메모리 사용을 최적화하는 가장 좋은 방법은 코드 실행에 필요한 데이터만 유지하는 것이다. 필요없어진 데이터에는 null을 할당하여 참조를 제거(dereference)하는 편이 좋다. 수동으로 참조 제거해야 할 대상은 주로 전역 변수 및 전역 객체의 프로퍼티이다. 지역 변수는 컨텍스트를 빠져나가는 순간 자동으로 참조가 제거된다.
값의 컨텍스트를 없애기 위해서 변수에서 참조를 제거하면 다음 가비지 콜렉션을 실행할 때 해당 메모리가 회수된다.
 
5장. 참조 타입
참조 값(객체)이란 특정 '참조 타입'의 인스턴스이다. ECMAScript에서 참조 타입은 데이터와 기능을 그룹으로 묶는 구조이며, 객체가 가져야 할 프로퍼티와 메서드를 정의한다는 점 때문에 '객체 정의'라 불리기도 한다.
객체를 생성할 때는 new 연산자 뒤에 객체를 생성하는 함수인 '생성자'를 쓴다.
var person = new Object(); // Object()는 생성자이며 네이티브 참조 타입
5.1 Object 타입
Object의 인스턴스를 명시적으로 생성하는 두 가지 방법. 첫 번째는 new 연산자와 Object() 생성자를 함께 쓴다:
var person = new Object();
person.name = "Nolboo";
person.age = 19;
다른 방법은 여러 가지 프로퍼티를 쉽게 정의할 수 있는 '객체 리터럴' 표기법:
var person = {
    name : "Nolboo",
    age : 19
};
왼쪽 중괄호({ 기호)는 할당 연산자(=) 다음에 값이 나올 것으로 예상되는 '표현식 컨텍스트'에 있으므로 표현식의 시작으로 간주하며, 객체 리터럴의 시작이다.
var person = {}; // new Object()와 같이 기본 프로퍼티와 메서드만 가진 객체
객체 리터럴 표기법은 프로퍼티를 여러 개 쓸 때 가독성을 확보하는 용도로만 쓰길 권한다.
객체 리터럴 표기법을 사용해 객체를 생성할 때는 Object 생성자를 호출하지 않는다. 파이어폭스 2까지는 호출했지만 3부터는 바뀌었다.
옵션 매개변수를 많이 쓸 때 유용하다. 이름 붙은 매개변수가 더 편리하지만, 옵션 매개변수의 숫자가 많아지면 관리하기 어렵다. 가장 좋은 방법은 필수적인 매개변수에는 이름을 붙이고 나머지 옵션 매개변수는 객체 리터럴로 받는 방법이다.
객체 프로퍼티는 보통 '점 표기법'을 써서 접근하지만 '대괄호 표기법'을 쓸 수도 있다. 대괄호 표기법은 변수를 써서 프로퍼티에 접근할 수 있으며, 프로퍼티 이름에 문법 에러 문자가 있거나 키워드 및 예약어에 해당하는 프로퍼티 이름에도 접근할 수 있다.
5.2 Array 타입
데이터의 순서 있는 목록이며, 배열 슬롯에 어떤 타입의 데이터라도 넣을 수 있으며, 데이터를 추가하면 자동으로 커진다.
배열을 만드는 두 가지 방법. 첫 번째는 Array 생성자를 쓴다:
var colors = new Array)();
숫자 하나만 넘기면 숫자 길이만큼의 배열이 만들어지나, 숫자가 아닌 매개변수를 넘기면 해당 데이터 하나만 가진 배열이 생성된다.
var colors = new Array(3);          // 데이터가 3개 있는 배열을 만든다
var names = new Array("Nolboo");    // 문자열 "Nolboo"만 있는 배열을 만든다
Array 생성자를 쓸 때는 new 연산자를 생략할 수 있다.
두 번째는 대괄호 안에 데이터를 쉼표로 구분하는 '배열 리터럴' 표기법이다:
var colors = ["red", "blue", "green"];  // 문자열이 3개 있는 배열을 만든다
var names = [];                         // 빈 배열을 만든다
length 프로퍼티는 배열에 저장된 데이터의 개수이며 항상 0 이상의 값을 반환한다. 흥미로운 것은 읽기 전용이 아니라서 값을 바꾸면 배열 길이가 그것에 맞게 바뀌면서 데이터를 제거하거나 빈 슬롯을 추가한다.
배열에는 최대 4,294,967,295개의 데이터를 담을 수 있다. 그 이상의 데이터를 담으려 하면 예외가 발생하여 오래 실행되는 스크립트 에러가 발생할 수 있다.
배열 감지
전역 스코프가 하나뿐인 단순한 웹 페이지에서는 instanceof 연산자를 쓴다. 웹 페이지에 프레임이 여러 개 있을 경우의 문제를 우회하기 위해 Array.isArray() 메서드를 사용하여 실행 컨텍스트와 무관하게 주어진 값이 배열인지를 알기 위한 것이다.
변환 메서드
toLocaleString(), toString(), valueOf() 메서드가 있다. toString()과 valueOf()는 쉼표로 분리된 문자열의 형태로 같은 값을 반환한다.
toLocaleString()을 배열에서 호출하면 각 값에서 toLocaleString()을 호출해서 문자열 값을 얻는다는 점이 나머지 두 메서드와 다른 점이다.
join() 메서드로 문자열 구분자를 지정할 수 있다. 매개변수를 쓰지 않거나 undefined를 쓰면 구분자로 쉼표를 사용한다.
배열에서 join(), toLocaleString(), toString(), valueOf() 메서드를 호출했을 때 null이나 undefined인 데이터는 빈 문자열로 표시된다.
스택 메서드
push()와 pop() 메서드는 배열의 기본 메서드이면서 배열을 스택처럼 동작하게 한다. 스택은 'LIFO: last-in-first-out' 구조이며, 마지막에 추가된 데이터가 제일 먼저 삭제된다. 스택에서 데이터 '삽입(push)'과 '제거(pop)'는 스택의 맨 위 단 한 지점에서만 발생한다.
push() 메서드의 매개변수 숫자는 제한이 없으며 받은 매개변수를 그대로 배열에 추가한 후 늘어난 배열 길이를 반환한다. pop() 메서드는 반대로 배열의 마지막 데이터를 제거하고 length 프로퍼티를 줄여서 반환한다.
큐 메서드
큐는 데이터 입출력을 'FIFO: first-in-first-out'로 제한하는 데이터 구조이다. 목록 마지막에 데이터를 추가하며 목록 맨 앞에서 데이터를 꺼낸다. shift() 메서드는 배열의 첫 번째 데이터를 꺼내서 반환하며 배열 길이는 1만큼 줄어든다.
unshift() 메서드는 shift()와 반대로 동작하며, 매개변수로 넘겨받은 데이터를 배열의 처음에 추가하며 늘어난 배열 길이를 반환한다.
정렬 메서드
배열 순서를 직접 조작하는 메서드는 reverse()와 sort() 두 가지이다. reverse() 메서드는 단순히 배열에 저장된 데이터 순서를 뒤집는다. sort() 메서드는 데이터를 정순, 즉 가장 작은 값이 첫 번째에 오고 가장 큰 값이 마지막에 오도록 정렬한다. 이를 위해 이면에서 String() 함수를 호출해 데이터를 문자열로 변환한 후에 이를 비교하여 순서를 판단한다. 숫자만으로 이루어진 배열에서 똑같이 동작하는 단점이 있다. 이럴 때는 '비교함수'를 넘겨서 순서를 조절한다.
sort() 메서드의 매개변수로 쓸 수 있는 비교 함수 예제:
function compare(value1, value2) {
    if (value1 < value2) {
        return -1;
    } else if (value1 > value2) {
        return 1;
    } else {
        return 0;
    }
}
reverse()와 sort()는 모두 자신을 호출한 배열에 대한 참조를 반환하므로, array.sort(compare).reverse() 와 같이 체인 형태로 쓸 수 있다.
숫자 타임이나 Date 객체처럼 숫자형 값을 반환하는 객체에서의 비교함수는 두 값을 빼기만 하면 된다.
조작 메서드
concat() 메서드는 현재 배열을 복사한 후 메서드의 매개변수를 새 배열 마지막에 추가하여 반환한다.
slice() 메서드는 매개변수를 하나만 넘기면 해당 인덱스에서 끝까지 모든 데이터를 가져오고, 매개변수를 두 개 넘기면 첫 번째 매개변수에 해당하는 인덱스부터 두 번째 매개변수에 해당하는 인덱스의 바로 앞까지 가져온다. 원래 배열은 전혀 건드리지 않는다.
매개변수를 음수로 넘기면 배열 길이 해당 값을 더한 숫자를 대신 사용한다. 예로, 길이가 5인 배열에서 slice(-2, -1)를 호출한 결과는 slice(3, 4)를 호출한 결과와 같다. 두 번째 매개변수가 첫 번째 매개변수보다 작으면 빈 배열을 반환한다.
splice() 메서드의 주요 목적은 배열 중간에 데이터를 삽입하는 것이며, 세 가지 방법으로 사용된다.
  • 삭제 - 첫 번째 매개변수(인덱스)부터 두 번째 매개변수(개수)만큼 삭제한다.
  • 삽입 - 삽입할 위치, 0(아무것도 삭제하지 않는다), 삽입할 데이터 순서로 3개 이상의 매개변수를 넘긴다.
  • 대체 - 삽입과 삭제를 조합한다. splice(2, 1, "red", "green")은 인덱스 2의 데이터를 삭제한 다음 문자열 "red"와 "green"을 인덱스 2에 삽입한다.
splice() 메서드는 항상 원래 배열에서 삭제한 데이터의 배열을 반환한다. 삭제한 것이 없다면 빈 배열을 반환한다.
위치 메서드
indexOf()와 lastIndexOf() 메서드에서 첫 번째 매개변수는 검색할 데이터이고, 두 번째 매개변수는 검색을 시작할 인덱스이다. indexOf() 메서드는 배열의 처음(인덱스 0)에서 검색을 시작하여 마지막까지 검색하고, lastIndexOf() 메서드는 배열의 마지막에서 검색을 시작하여 처음까지 검색한다. 두 메서드는 찾아낸 데이터의 인덱스를 반환하며, 찾지 못하면 -1을 반환한다. === 연산자로 비교해서 일치하는(타입까지 일치하는) 데이터를 검색한다.
var numbers = [1,2,3,4,5,4,3,2,1];
alert(numbers.indexOf(4));
alert(numbers.lastIndexOf(4));
alert(numbers.indexOf(4, 4));
alert(numbers.lastIndexOf(4, 4));
var person = { name: "Nolboo" };
var people = [{ name: "Nolboo" }];
var morePeople = [person];
alert(people.indexOf(person));
alert(morePeople.indexOf(person));
세번째 결과부터 잘 이해가 안됨;;
반복 메서드
반복 메서드는 배열의 각 데이터에서 실행할 함수와 함수를 실행할 스코프 객체를 매개변수로 받는다. 콜백함수는 모두 데이터, 데이터의 인덱스, 배열 자체의 세 가지 매개변수를 받는다.
  • every() - 반환값이 전부 true이면 true를 반환한다.
  • filter() - 반환값이 true인 데이터를 새 배열에 저장하여 반환한다.
  • forEach() - 반환값이 없으며, 해당 배열에 for 문을 실행한 것과 같다.
  • map() - 결과를 새 배열에 저장하여 반환한다.
  • some() - 반환값 중 하나라도 true이면 true를 반환한다.
감소 메서드
reduce()와 reduceRight()는 배열을 순회하며 콜백함수를 실행하고 값을 하나 만들어 반환한다. reduce() 메서는 배열의 첫 번째 데이터에서 시작하여 마지막까지, reduceRight()는 배열의 마지막 데이터에서 시작하여 첫 번째까지 진행한다.
첫 번째 매개변수는 각 데이터에서 실행할 콜백 함수이고, 두 번째 매개변수는 감소 작을 시작할 초기값이다. 콜백함수가 넘겨받는 매개변수는 이전 값, 현재 값, 현재 값의 인덱스, 현재 배열 네 가지이다. 콜백함수가 반환하는 값은 자동으로 다음 데이터에서 실행하는 콜백 함수의 첫 번째 매개변수가 된다.
5.3 Date 타입
Date 타입은 1970년1월1일 자정부터의 밀리초 숫자로 저장하며, 285,616년 전후의 날짜까지를 정확히 표현할 수 있다.
날짜 객체를 생성할 때는 new 연산자 다음에 Date 생성자를 쓰며, 매개변수를 넘기지 않으면 현재 날짜와 시간이 저장된다.
var now = new Date();
밀리초 매개변수의 메서드는 Date.parse()와 Date.UTC()가 있다.
Date.parse() 메서드는 날짜 문자열을 받고 밀리초로 변환을 시도한다.
  • 월/일/년(6/13/2004)
  • 월이름 일, 년(January 12, 2004)
  • 요일 월이름 일 년 시:분:초 타임존(Tue May 25 2004 00:00:00 GMT-0700)
  • ISO 8601 확장형식 YYYY-MM-DDTHH:mm:ss.sssZ(2004-05-25T00:00:00) 이 형식은 ECMAScript 5 호환 브라우저에서만 지원된다.
올바른 날짜 형식이 아닐 때는 NaN을 반환한다.
Date 생성자는 (Date.parse() 메서드 없이) 문자열을 넘겨받으면 이면에서 Date.parse()를 호출한다.
Date.UTC()의 매개변수는 해당 시각의 년, 월 인덱스(0이 1월), 일(1~31), 시(0~23), 분, 초, 밀리초이다. 필수는 년, 월 인덱스 2개이며, 일을 생략하면 1일로 간주하며, 다른 매개변수는 모두 0으로 간주한다.
Date 생성자에 Date.UTC() 형식의 매개변수를 넘기면 이면에서 Date.UTC()를 호출하지만 날짜와 시간을 GMT가 아닌 지역 시간을 사용한다.
ECMAScript 5에서는 현재 시각을 밀리초로 반환하는 now() 메서드가 추가되었다. 코드의 실행시간을 측정하는 프로파일링 작업을 쉽게 할 수 있다.
상속된 메서드
Date 타입 역시 toLocaleString(), toString(), valueOf() 메서드를 오버라이드하나, 조금 다른 값을 반환하며 브라우저마다 반환 형식이 상당한 차이가 있어 디버그 목적으로나 쓸만하지 사용자에게 표시하기에는 적당하지 않다.
valueOf() 메서드가 반환하는 값에는 문자열이 전혀 들어있지 않은 밀리초 표현을 쓴다. 이를 통해 날짜 순서를 쉽게 비교할 수 있다.
날짜 표시 메서드
toDateString(), toTimeString(), toLocaleDateString(), toLocaleTimeString(), toUTCString 등이 있으나 반환하는 문자열이 브라우저에 따라 크게 달라 사용자 인터페이스에 일관된 날짜 형식을 쓰고 싶다면 그대로 사용할 수는 없다.
날짜/시간 부속 메서드
날짜의 특정 부분을 가져오거나 설정하는 데 쓰인다. 표 참조
5.4 RegExp 타입
var expression = /pattern/flags;
패턴 부분에는 정규 표현식을 나타내는 식을 쓰며, 문자 클래스, 수량자, 그룹, 룩어헤드, 역참조 등이 포함된다. 플래그를 통해 어떻게 동작할지 나타내며, 세 가지가 있다.
  • g - 전역모드. 지정하면 문자열에서 패턴을 찾는 즉시 종료하지 않고 문자열 전체에서 동작한다.
  • i - 대소문자 비구분 모드.
  • m - 여러 줄 모드. 테스트의 줄 끝에 도달해도 멈추지 않고 계속 패턴을 찾는다.
다음 '메타문자'를 패턴에 쓸 때는 반드시 역슬래시로 이스케이프해야 한다.
( [ { \ ^ $ | } ] ) ? * + .
정규 표현식 리터럴이나 RegExp 생성자를 사용하여 정규 표현식을 생성할 수 있다. RegExp 생성자의 매개변수는 "패턴이 될 문자열"과 옵션인 "플래그를 나타내는 문자열"이며, RegExp 생서자에 정규 표현식 리터럴을 넘기면 안 된다. RegExp 생성자에 메타 문자를 쓸 때는 반드시 이중으로 이스케이프해야 한다.
ECMAScript 3판에서 리터럴로 생성한 정규 표현식은 항상 같은 RegExp 인스턴스를 공유하지만 RegExp 생성자는 호출할 때마다 새로운 인스턴스를 생성한다. ECMAScript 5에서는 리터럴로 정규 표현식을 생성할 때도 RegExp 생성자를 호출하게끔 명확히 정했다.
정규 표현식 인스턴스 프로퍼티
RegExp 인스턴스에는 다음 프로퍼티가 있으며 각 프로퍼티는 패턴에 대한 정보를 포함한다.
  • global - g 플래그 설정 여부 불리언 값.
  • ignoreCase - i 플래그 설정 여부 불리언 값.
  • lastIndex - 패턴 매칭의 시작 위치를 나타내는 정수 값이며, 항상 0에서 시작한다.
  • multiline - m 플래그 설정 여부 불리언 값.
  • source - 정규 표현식을 생성한 문자열. 항상 리터럴 형식으로 반환하되 여닫는 /문자는 포함되지 않는다. 생성자를 통해 생성되었더라도 리터럴 형식으로 반환한다.
정규 표현식 인스턴스 메서드
가장 많이 쓰는 메서드는 그룹을 캡처할 의도로 만들어진 exec() 메서드이며, 패턴을 테스트할 문자열을 매개변수로 받고 패턴에 일치하는 문자열 배열을 반환한다. 일치하는 부분을 찾을 수 없을 때는 null을 반환한다. 반환하는 배열은 Array의 인스턴스인 동시에 일치 위치를 나타내는 index 프로퍼티, exec() 메서드에 넘긴 문자열인 input 프로퍼티가 추가된다. exec() 메서드가 반환하는 첫 번째 데이터는 패턴에 일치하는 부분 전체이며, 다른 데이터는 표현식에서 캡처한 부분이다. 캡처 그룹이 없다면 반환하는 배열에는 데이터가 단 하나만 존재한다.
exec() 메서드는 g 플래그가 설정되어 있더라도 한 번에 한 가지 매치에 관한 정보만 반환한다. g 플래그가 설정되어 있지 않으면 exec()를 같은 문자열에 여러 번 호출하더라도 첫 번째 매치에 대한 정보만 반환한다. 패턴에 g 플래그가 설정되어 있으면 exec()를 호출할 때마다 문자열 안쪽으로 더 깊숙이 들어가며 검색한다.
test() 메서드는 문자열이 패턴에 일치할 때는 true를 반환하고 그렇지 않으면 false를 반환한다. if문에서 자주 사용한다.
객체 프로토타입에서 상속한 메서드 toLocaleString()과 toString()은 정규 표현식을 어떻게 생성했는지에 관계없이 리터럴 표현을 반환한다. valueOf() 메서드는 정규 표현식 자체를 반환한다.
RegExp 생성자 프로퍼티
정식 이름과 짧은 이름이 있는데 오페라는 짧은 이름을 지원하지 않는다. 다음 표는 RegExp 생성자의 프로퍼티이다.
정식이음
짧은 이름
설명
input
$_
마지막으로 테스트한 텍스트
lastMatch
$&
마지막으로 일치한 문자열
lastParen
$+
마지막으로 일치한 캡처 그룹
leftContext
$'
input 텍스트에서 lastMatch 앞에 있는 문자열
multiline
$*
모든 정규 표현식이 다중 행 모드를 사용해야 하는지 표현하는 불리언 값
RightContext
$'
input 텍스트에서 lastMatch 다음에 오는 문자열
짧은 이름은 반드시 대괄호 표기법을 써야한다.
정규 표현식 생성자에는 캡처 그룹을 아홉 개까지 지정할 수 있는 프로퍼티도 있으며, RegExp.$1 형식으로 쓰면 첫 번째 캡처 그룹을 나타내고, RegExp.$9은 아홉 번째 캡처 그룹을 나타낸다. exec()나 test()를 호출할 때마다 자동으로 값이 설정된다.
패턴의 한계
ECMAScript의 정규 표현식은 완전히 개발된 상태이지만 펄 같은 언어에서 가능한 고급 정규 표현식 기능에는 미치지 못한다. 다음 기능은 ECMAScript 정규 표현식에서 지원하지 않는 기능이다. 자세한 정보는 Regular-Expressions.info - Regex Tutorial, Examples and Reference - Regexp Patterns를 참고한다.
  • 테스트의 처음과 마지막에 일치하는 \A와 \Z
  • 룩비하인드
  • 병합 클래스
  • 최소 그룹(atomic group)
  • 유니코드 지원(한 번에 한 문자를 찾는 기능은 지원한다.)
  • 이름 붙은 캡처 그룹
  • s(한 줄 모드), x(공백 무시 모드) 플래그
  • 조건문
  • 정규 표현식 주석
5.5 Function 타입
모든 함수는 function 타입의 인스턴스이며 프로퍼티와 메서드가 있으며, 함수 이름은 단순히 함수 객체를 가리키는 포인터이다.
보통 함수 선언 문법(함구 표현식)을 통해 정의한다.
fuction sum (num1, num2) {
    return num1 + num2;
}
함수 선언은 다음 함수 표현식과 거의 정확히 일치한다.
var sum = function (num1, num2) {
    return num1 + num2;
};
이 코드는 변수 sum을 정의하면서 함수로 초기화하였다. 함수 표현식에서 function 키워드 다음에 함수 이름이 없는 점에 주목한다. 변수 sum으로 함수를 참조하므로 함수 이름은 필요치 않다. 또한 표현식 마지막에 다른 변수 초기화 문장과 마찬가지로 세미콜론을 쓴 점도 눈여겨 본다.
함수를 정의하는 마지막 방법은 Function 생성자를 이용하는 방법이다. Function 생성자에 넘기는 매개변수 숫자에는 제한이 없다. 매개변수 중 마지막은 함수 바디로 간주하며 그 이전에 있는 매개변수는 함수의 매개변수로 전달된다.
var sum = new Function("num1", "num2", "return num1 + num2") // 권장하지 않음.
오버로딩 없음(다시 설명합니다)
함수 이름이 단순한 포인터임을 이해하면 ECMAScript에서 함수 오버로딩이 불가능한 이유도 이해할 수 있다.
함수 선언 vs 함수 표현식
자바스크립트 엔진이 실행 컨텍스트에 데이터를 불러올 때 중요한 차이가 하나 있다. 함수 선언은 어떤 코드도 실행하기 전에 이미 모든 실행 컨텍스트에 접근하고 실행할 수 있지만, 함수 표현식은 코드 실행이 해당 줄까지 진행하기 전에는 사용할 수 없다.
alert(sum(10,10));
function sum(num1, num2) {
    return num1 + num2;
}
이 코드는 아무 에러 없이 실행되는데, 코드를 실행하기 전에 '함수 선언 호이스팅'을 통해 함수 선언을 읽고 실행 컨텍스트에 추가하기 때문이다. 자바스크립트 엔진은 코드를 평가할 때 제일 먼저 함수 선언을 찾은 다음 이들을 맨 위로 올린다. 즉 함수 선언이 소스코드에서 해당 함수를 실행하는 부분보다 뒤에 있어도 자바스크립트 엔진이 함수 선언을 '끌어올린다(hoist)'.
alert(sum(10,10));
var sum = function (num1, num2) {
    return num1 + num2;
};
위의 코드는 에러를 내는데, 함수가 함수 선언이 아니라 초기화 문장의 일부이기 때문이다. 코드 첫 줄에서 '예기치 못한 식별자(unexpected identifier)'에러를 낸다. 이런 차이를 제외하면 함수를 이름으로 호출할 때 두 문법 사이에 다른 차이는 없다.
함수 표현식을 쓰면서도 함수 선언처럼 보이게, 즉 var sum = function sum() {}처럼 쓸 수 있다.
값처럼 쓰는 함수
ECMAScript에서 함수 이름은 단지 변수일 뿐이므로 함수도 다른 값이 올 수 있는 곳이라면 어디든 올 수 있으며, 함수를 다른 함수에 매개변수로 넘기거나, 함수가 실행 결과로 다른 함수를 반환하는 일이 가능하다.
함수의 내부 구조
함수 내부에는 arguments, this라는 특별한 객체가 있다. arguments 객체는 배열과 비슷한 객체이며 함수에 전달된 매개변수를 모두 포함한다.
this는 함수가 실행 중인 컨텍스트 객체에 대한 참조이다. 함수를 웹 페이지의 전역 스코프에서 호출했다면 this 객체는 window를 가리킨다.
caller 프로퍼티에는 해당 함수를 호출한 함수에 대한 참조를 저장하며 전역 스코프에서 호출했다면 null이 저장된다.
함수의 프로퍼티와 메서드
모든 함수에 공통인 프로퍼티는 length와 prototype이다. length 프로퍼티는 함수가 넘겨받을 것으로 예상하는 이름 붙은 매개변수의 숫자이다.
prototype 프로퍼티는 모든 참조 타입의 인스턴스 메서드가 존재하는 곳이다. 즉 toString()이나 valueOf() 같은 메서드는 prototype에 존재하며 객체 인스턴스는 이에 접근한다. prototype 프로퍼티는 개발자 자신만의 참조 타입과 상속을 정의할 때 매우 중요하며, 열거할 수 없는 프로퍼티이므로 for-in 문에 나타나지 않는다.
apply()와 call() 메서드는 소유자인 함수를 호출하면서 this를 넘기는데, 결과적으로 함수 내부에서 this 객체의 값을 바꾸는 것이나 마찬가지이다. apply() 메서드는 매개변수로 소유자 함수에 넘길 this와 매개변수 배열을 받는다. 두 번째 매개변수는 Array의 인스턴스일 수도 있고 arguments 객체일 수도 있다. call 메서드는 매개변수를 전달하는 방식이 다르다. this가 첫 번째 매개변수인 것은 같지만, 반드시 매개변수를 각각 나열해야 한다. arguments 객체를 그대로 전달해도 되거나 데이터가 배열 형태로 준비되어 있다면 apply()가 나을 것이고, 그렇지 않다면 call90이 나을 것이다.
ECMAScript 5판에서 정의된 bind()는 새 함수 인스턴스를 만드는데 그 this는 bind()에 전달된 값이다.
5.6 원시 래퍼 타입
Boolean, Number, String은 원시 값을 편리하게 조작하기 위해 디자인된 참조타입이다. 원시 값을 읽을 때마다 이에 해당하는 래퍼 타입이 이면에서 생성되므로 메서드를 사용할 수 있다.
참조 타입과 원시 래퍼 타입의 주요 차이는 그 생명 주기이다. new 연산자를 사용해 참조 타입의 인스턴스를 만들면 스코프를 벗어날 때까지 메모리에 존재하지만, 자동으로 생성된 원시 래퍼 타입은 코드의 해당 행을 벗어나는 즉시 파괴된다. 따라서 원시 래퍼 타입에는 런타임에 프로퍼티나 메서드를 추가할 수 없다.
Object 생성자에 문자열을 넘기면 String의 인스턴스가 생성되며 숫자를 넘기면 Number의 인스턴스가, 불리언을 넘기면 Boolean의 인스턴스가 생성된다. 염두에 둘 점은 new를 사용해 원시 래퍼 생성자를 호출한 것과 같은 이름의 형 변환 함수를 호출한 결과는 다르다는 것이다.
불리언 타입
원시 불리언 값과 Boolean 객체를 반드시 구분할 수 있어야 하며 Boolean 객체는 절대 쓰지 마라.
Number 타입
toFixed() 메서드는 지정한 만큼의 정확도로 소수점을 찍은 문자열을 반환하며, 매개변수로 지정한 자리 수보다 크다면 반올림한다.
일반적으로 소수점 이하 20자리까지 지원한다.
toExponential() 메서드는 숫자를 지수 표기법 문자열로 반환한다.
toPrecision() 메서드는 숫자에 따라 지수 표기법이나 소수점 표기법으로 선택하여 반환한다. 숫자 표현에 사용할 총 자리 수를 매개변수로 받는다(지수 부분은 받지 않는다)
일반적으로 1부터 21 사이의 자리 수를 넘길 수 있다.
String 타입
문자열을 나타내는 객체이며 String 생성자를 쓴다.
var stingObject = new String("hello world");
글자 메서드
charAt()와 charCodeAt()는 원하는 문자의 인덱스를 매개변수로 받는다. charAt()은 한 글자의 문자열로 반환하고, charCodeAt()는 해당하는 문자의 문자코드를 반환한다.
문자열 조작 메서드
concat() 메서드는 문자열을 병합한다. + 연산자가 더 자주 쓰이며 더 빨리 동작한다.
slice(), substr(), substring() 메서드는 문자열 일부로 새 문자열을 만든다. 어디서부터 가져올 것인가를 첫 번째 매개변수로, 어디까지(직전)가 두 번째이다. substr()의 두 번째 매개변수는 문자 몇 개를 가져올지이다. 세 가지 모두 두 번째 매개변수를 생략하면 열 전체 길이가 기본 값이다.
var = stringValue = "hello world";
alert(stringValue.slice(3));        // "lo world"
alert(stringValue.substring(3));    // "lo world"
alert(stringValue.substr(3));       // "lo world"
alert(stringValue.slice(3, 7));     // "lo w"
alert(stringValue.substring(3, 7)); // "lo w"
alert(stringValue.substr(3, 7));    // "lo worl"
slice()는 음수 매개변수를 받으면 전체 문자열 길이에 해당 매개변수를 더한 값을 사용한다. substr()은 첫 번째 매개변수에 음수를 받으면 전체 문자열 길이에 해당 매개변수를 더한 값을 사용한다. 두 번째 매개변수가 음수이면 0을 사용한다. substring()은 음수 매개변수를 모두 0으로 바꾼다.
문자열 위치 메서드
indexOf()와 lastIndex()는 문자열의 위치를 찾으면 위치를 반환하며 찾지 못했을 때는 -1을 반환한다. indexOf()는 문자열 처음에서, lastIndexOf()는 문자열 마지막에서 검색을 시작한다. 두 번째 매개변수는 옵션이며, 검색을 시작할 인덱스이다.
trim() 메서드
문자열을 복사한 후 앞뒤 공백을 모두 제거한 결과를 반환한다.
대소문자 메서드
toLowerCase(), toLocaleLowerCase(), toUpperCase(), toLocaleUpperCase() 네 가지. 일부 언어에서는 대소문자 변환에 따른 특별한 규칙이 필요하며 이 때문에 지역 메서드가 필요하다. 일반적으로 작성한 코드가 어느 지역에서 실행될지 모른다면 지역 메서드를 쓰는 편이 안전한다.
문자열 패턴 매칭 메서드
String 타입에서 문자열 내에서 패턴 매칭하는 메서드 중 가장 많이 쓰이는 것은 match()이다. RegExp 객체의 exec() 메서드와 같은 결과를 반환한다. 매개변수로 정규 표현식 리터럴이나 RegExp 객체를 하나 받는다.
search() 메서드는 패턴에 일치하는 첫 번째 문자열 인덱스를 반환하며 찾지 못했을 때는 -1을 반환한다. 항상 문자열의 처음에서 검색을 시작한다.
replace()는 문자열 일부를 바꾼다. 첫 번째 매개변수를 RegExp 객체 또는 문자열(단, 이 문자열을은 정규표현식으로 변환되지 않는다)이고, 두 번째 매개변수는 문자열 또는 문자열을 반환하는 함수이다. 일치하는 문자열 전체를 바꾸려면 정규 표현식에 g 플래그를 써서 넘긴다.
두 번째 매개변수에 문자열을 쓸 대 정규 표현식에서 얻은 정보를 다양한 방법으로 응용하는 특수문자가 있다.
특수문자
대응 문자열
$$
$
$&
패턴에 일치하는 문자열 전체. RegExp.lastMatch와 같다.
$'
일치하는 문자열 앞의 텍스트. RegExp.rightContext와 같다.
$'
일치하는 문자열 다음의 텍스트. RegExp.leftContext와 같다.
$n
'n'번째 캡처 그룹이며 'n'은 0부터 9사이.
$nn
'nn'번째 캡처 그룹이며 'nn'은 00부터 99사이.
replace()의 두 번째 매개변수에는 함수도 쓸 수 있다. 일치하는 것이 하나뿐일 때 콜백함수는 자동으로 매개변수를 세 개 받는다. 일치하는 문자열, 해당 문자열의 위치, 전체 문자열. 일치하는 것이 여럿일 때는 이들 모두가 매개변수로 전달되며 그다음에는 매치한 위치, 마지막으로 원래 문자열이 전달된다. 콜백함수는 반드시 문자열을 반환해야 하며 이 문자열로 일치한 문자열을 대체합니다.
htmlEscape() 함수는 HTML에서 사용할 수 있도록 특수문자를 이스케이프한다. HTML에서 그대로 쓸 수 없는 <, >, &, " 문자를 이스케이프하는 가장 쉬운 방법은 정규 표현식으로 해당 문자를 검색한 다음에 HTML 엔티티를 반환하는 함수를 쓰는 것이다.
split() 메서드는 텍스트를 구분자를 기준으로 분리해서 배열에 담아 반환한다. 구분자에는 문자열과 RegExp 객체를 쓸 수 있는데 문자열을 정규 표현식으로 간주하지는 않는다. 두 번째 매개변수(옵션)는 반환받을 배열의 크기를 지정하는 숫자이다.
split()과 정규 표현식의 캡처 그룹의 브라우저 간 비호환성 문제는 스티브 레비슨의 자바스크립트 split 버그가 마침내 수정되었다을 읽어본다.
localeCompare() 메서드
문자열 두 개를 비교한 후 -1, 0, 양수(대부분 1)를 반환한다. 메서드를 호출한 텍스트가:
  • 매개변수로 넘긴 문자열보다 알파벳 순서상 뒤에 있다면 : -1
  • 매개변수 문자열과 일치하면 : 0
  • 매개변수로 넘긴 문자열보다 알파벳 순서상 앞에 있다면 : 양수(대부분 1이지만 브라우저에 따라 값이 다룰 수 있어 추상화한 함수를 만드는 편이 좋다)
fromCharCode() 메서드
String 생성자에서 문자 코드를 받아 이를 문자열로 변환하는 메서드.
HTML 메서드
자바스크립트에서 동적으로 HTML 형식을 생성하기 위한 메서드이나 시맨틱 마크업을 해치므로 거의 사용하지 않는다.
5.7 내장된 싱글톤 객체
Global, Math. 싱글톤(singleton)이란 인스턴스를 한 개만 만들도록 하는 객체. Object, Array, String 등은 인스턴스를 여럿 만들어 사용하지만 Math 객체는 인스턴스를 만들지 않고 메서드의 네임스페이스 용도로만 사용한다.
Global 객체
Global 객체는 명시적으로 접근할 수 없다는 점에서 ECMAScript에서 가장 독특한 객체이다. ECMA-262는 Global 객체를 소유자가 없는 모든 프로퍼티와 메서드를 담는 객체로 정의한다. 사실 전역 변수나 전역 함수라는 것은 존재하지 않는다. 전역에서 정의한 변수와 함수는 모두 Global 객체의 프로퍼티가 된다.
URI 인코딩 메서드
브라우저에 전달한 URI를 인코드하는 메서드. 특별한 UTF-8 인코딩을 써서 URI에 사용할 수 없는 문자를 브라우저가 인식하고 이해할 수 있는 문자로 바꾼다.
encodeURI() 메서드는 전체 URI를, encodeURIComponent()는 URI 일부분만 조작한다. encodeURI()는 :이나 /, ?, #처럼 URI 일부분으로 쓰이는 특수문자는 인코드하지 않지만 encodeURIComponent()는 비표준 문자를 모두 인코드하며, URI 마지막에 추가할 문자열에만 사용할 수 있다.
일반적으로 베이스 URI 뒤에 추가할 쿼리스트링을 인코드하는 경우가 많으므로 encodeURIComponent()를 자주 쓰게 된다.
decodeURI()와 decodeURIComponent()는 반대.
위 네 가지 URI 메서드는 ECMA-232 3판에서 폐기한 escape(), unescape() 메서드를 대체한다. 배포할 코드에 ASCII 문자만 변환하는 escape()나 enscape()를 쓰지 마라.
eval() 메서드
ECMAScript에서 가장 강력한 메서드이다. ECMAScript 인터프리터 자체인 듯 동작하며 매개변수로 문자열 하나 받는데 이 문자열은 실행할 수 있는 ECMAScript 코드여야 한다.
다음 두 개의 문장은 같다.
eval("alert('hi')");
alert("hi");
인터프리터가 eval()을 만나면 매개변수를 실제 ECMAScript 문자으로 해석하여 eval()이 있던 위치에 삽입한다. eval()이 실행하는 코드는 eval()을 호출한 실행 컨텍스트의 일부분으로 간주되며 해당 컨텍스트와 같은 스코프 체인을 가진다.
eval() 내부에서 정의한 변수나 함수는 끌어올림의 대상이 아니다. 코드 파싱 단계에서는 문자열이다. 변수나 함수로 정의되는 시점은 eval()이 실행되는 시점이다.
스트릭트 모드에서는 eval() 내부에서 정의한 변수나 함수에 접근할 수 없으며, eval에 값을 할당할 수 없다.
문자열을 코드로 변환하는 기능은 대단히 강력하지만 대단히 위험하기도 하다. eval()을 쓸 때는 항상 주의해야 하며, 사용자가 입력한 데이터에 eval()을 쓸 때는 특히 더 조심해야 한다. 악의적인 사용자가 당신의 사이트나 애플리케이션 보안을 해치는 값을 입력할 수 있기 때문이다.(코드 주입)
Global 객체의 프로퍼티
undefined, NaN, Infinity, Object, Array, Function, Boolean, String, Number, Date, RegExp, Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError 등이 있으며, ECMAScript 5판에서는 undefined, NaN, Infinity에 값을 할당할 수 없음을 명확히 했다. 이들에 값을 할당하려 하면 스트릭트 모드가 아닐 때에도 에러가 난다.
Widnow 객체
ECMA-262에서는 Global 객체에 직접 접근할 수 없도록 했지만, 웹 브라우저에서는 window 객체를 통해 Global 객체에 접근할 수 있다. 전역 스코프에서 선연한 변수와 함수는 모두 window 객체의 프로퍼티가 된다.
var color = "red";
function sayColor(){
    alert(window.color);
}
window.sayColor();  // "red"
Math 객체
수학 공식과 각종 상수를 Math 객체에 저장한다. 필요한 계산이 Math 객체에 구현되어 있다면 직접 만들기보다 빠르다.
Math 객체의 프로퍼티
프로퍼티
설명
Math.E
자연로그의 밑수인 e의 값
Math.LN10
10의 자연로그
Math.LN2
2의 자연로그
Math.LOG2E
e의 밑수가 2인 로그(base 2)
Math.LOG10E
e의 밑수가 10인 로그(base 10)
Math.PI
파이값
Math.SQRT1_2
1/2의 제곱근
Math.SQRT2
2의 제곱근
min()과 max() 메서드
min()과 max() 메서드는 한 그룹의 숫자 중에서 가장 작은 숫자와 가장 큰 숫자를 찾는다. 매개변수 숫자에 제한이 없다.
배열 데이터 중에서 최대값이나 최소값을 찾을 때는 apply() 메서드를 쓸 수 있다.
var values = [1, 2, 3, 3, 4, 5, 6, 7, 8];
var max = Math.max.apply(Math, values);
이 테크닉의 요점은 apply()의 첫 번째 매개변수로 Math 객체를 넘겨서 this가 정확히 설정되도록 하는 것이다. 이렇게 하면 두 번째 매개변수로 배열을 넣었을 때 올바르게 동작한다.
반올림 메서드
Math.ceil()은 올림, Math.floor()는 내림, Math.round()는 반올림이다.
random() 메서드
0과 1 사이의 난수를 반환하되 0이나 1을 반환하지는 않는다.
number = Math.floor(Math.random() * total_number_of_choices + first_possible_number)
경우의 수를 세는 것보다 범위만 제공하여 그 사이의 난수를 반환하는 함수를 만드는 편이 편리하다.
function selecForm(lowerValue, upperValue) {
    var choices = upperValue - lowerValue + 1;
    return Math.floor(Math.random() * choices + lowerValue);
}
var num = selectForm(2,10);
alert(num); // 2 10사이의 난수. 2 10을 포함
var colors = ["red", "green", "blue", "yellow", "black", "purple", "brown"];
var color = colors[selectFrom(0, colors.length-1)];
기타 메서드
메서드
반환값
Math.abs(num)
num 절대값
Math.exp(num)
Math.E의 num제곱
Math.log(num)
num의 자연로그
Math.pow(num, power)
num의 power제곱
Math.sqrt(num)
num의 제곱근
Math.acos(x)
x의 아크코사인
Math.asin(x)
x의 아크사인
Math.atan(x)
x의 아크탄젠트
Math.atan2(y, x)
y/x의 아크탄젠트
 
 
6장. 객체 지향 프로그래밍
객체지향 언어는 일반적으로 클래스를 통해 같은 프로퍼티와 메서드를 가지는 객체를 여러 개 만든다는 특징이 있지만, ECMAScript에는 클래스라는 개념이 없다.
ECMA-262의 객체 정의는 "프로퍼티의 순서 없는 컬렉션이며 각 프로퍼티는 원시값이나 객체, 함수를 포함한다"이며, 특별한 순서가 없는 값의 배열이란 의미이다. ECMAScript 객체는 해시 테이블이며, 이름-값 쌍의 그룹이며 각 값은 데이터나 함수가 될 수 있다.
모든 객체는 참조 타입을 바탕으로 생성된다.
6.1 객체에 대한 이해
객체를 만드는 가장 단순한 방법은 Object의 인스턴스를 만들고 프로퍼티와 메서드를 추가하는 것이다.
var person = new Object();
person.name = "Nicholas";
person.age = 29;
person.job = "Software Engineer";
person.sayName = function() {
    alert(this.name);
};
초기에는 위의 패턴을 자주 사용했으나 몇 년이 지나면서 객체 리터럴 패턴을 더 많이 쓴다:
var person = {
    name: "Nicholas",
    age: 29,
    job: "Software Engineer",
sayName: function() {
        alert(this.name);
    }
};
프로퍼티 타입
ECMA-262 5판에서는 프로퍼티의 특징을 내부적으로만 유효한 속성에 따라 설명하며, 속성이 자바스크립트 엔진 내부에서 구현하므로 자바스크립트에서 직접적으로 접근할 수 없다. [[]]로 감싸서 내부 속성임을 나타낸다.
데이터 프로퍼티
  • [[Configurable]] - 삭제/변경/변환. 기본값은 true.
  • [[Enumerable]] - for-in 루프에서 반환. 기본값은 true.
  • [[Writable]] - 값 변경. 기본값은 true.
  • [[Value]] - 실제 데이터 값. 기본값은 undefined
Object.defineProperty() 메서드를 써서 속성 값을 바꿀 수 있다. Object.defineProperty()를 여러 번 호출할 수 있지만, 일단 Configurable을 false로 지정하면 제한이 생긴다. 프로퍼티 값을 따로 명시하지 않는다면 기본 값은 false이다.
접근자 프로퍼티
  • [[Configurable]]
  • [[Enumerable]]
  • [[Get]] - 프로퍼티를 읽을 때 호출할 함수. 기본 값은 undefined.
  • [[Set]] - 프로퍼티를 바꿀 때 호출할 함수. 기본 값은 undefined.
접근자 포로퍼티는 일반적으로 프로퍼티의 값을 바꿨을 때 해당 프로퍼티만 바뀌는 게 아니라 부수적인 절차가 필요한 경우에 사용한다.
getter 함수만 지정하면 해당 프로퍼티는 읽기 전용이 되고, 수정 시도는 모두 무시되거나 스트릭트 모드에선 에러가 발생한다. setter만 지정된 프로퍼티는 읽으려 하면 undefined를 반환하며 스트릭트 모드에선 에러가 발생한다.
다중 프로퍼티 정의
프로퍼티 속성 읽기
Object.getOwnPropertyDescriptor() 메서드로 프로퍼티의 서술자 프로퍼티를 읽을 수 있다.
 
 
자바스크립트 객체 상세
자바스크립트의 - 가장 자주 사용되고 가장 기본적인 - 핵심 데이터 타입은 객체 데이터 타입이다. 자바스크립트는 한 개의 복잡한 데이터 타입인 객체 데이터 타입이 있으며, 5개의 단순한 데이터 타입이 있다: 숫자, 문자열, 불린, undefined, null. 단순한 (원시적인) 데이터 타입은 불변 즉, 변경할 수 없으나, 객체는 변경할 수 있다.
객체란 무엇인가
객체는 이름-값 쌍으로 저장되는 원시 데이터(때때로 참조 데이터 타입)의 순서 없는 목록이다. 목록의 각 항목은 프로퍼티라고 불리며(함수는 메서드로 불린다), 각 프로퍼티의 이름은 유일해야 하고, 하나의 문자열 또는 숫자가 될 수 있다.
간단한 객체:
var myFirstObject = {firstName: "Richard", favoriteAuthor: "Conrad"};
반복하면: 객체를 이름-값 쌍으로 저장된 목록 안에 항목과 프로퍼티를 포함하는 목록으로 생각하라. 위의 예제의 프로퍼티 이름은 firstName과 favoriteAuthor이다. 각각의 값은 "Richard"와 "Conrad"이다.
프로퍼티 이름은 문자열이나 숫자가 될 수 있으나, 프로퍼티 이름이 하나의 숫자라면 대괄호 표기법으로 접근되어야 한다. 대괄호 표기법은 나중에 더 자세히. 프로퍼티 이름이 숫자로 된 객체의 예제:
var ageGroup = {30: "Children", 100:"Very Old"};
console.log(ageGroup.30) // 에러가 발생한다.
// "Children" 값을 얻기 위해서는 프로퍼티 30의 값은 다음과 같이 접근해야 한다.
console.log(ageGroup["30"]); // Children
//프로퍼티 이름에 숫자를 사용하길 피하는 것이 가장 좋다.
자바스크립트 개발자로서 여러분은 주로 데이터를 저장하고 여러분 자신의 커스텀 메서드와 함수를 만들기 위해, 매우 자주 객체 데이터 타입을 사용할 것이다.
참조 데이터 타입과 원시 데이터 타입
참조 데이터 타입과 원시 데이터 타입의 주요 차이점 중 하나는 참조 데이터 타입의 값은 변수에 직접 저장되지 않고, 참조로 저장되며, 원시 데이터 타입은 값으로 저장된다는 것이다. 예로:
    // 원시 데이터 타입 문자열은 값으로 저장된다.
    var person = "Kobe";
    var anotherPerson = person; // anotherPerson = person의 값
    person = "Bryant"; // person의 값이 바뀌었다.
console.log(anotherPerson); // Kobe
    console.log(person); // Bryant
"Bryant"로 person을 변경했을지라도, anotherPerson 변수는 person이 가졌던 값을 그대로 유지하는 것을 주목할 필요가 있다.
위에서 예시한 값으로 저장되는 원시 데이터와 참조로 저장되는 객체를 비교하라:
    var person = {name: "Kobe"};
    var anotherPerson = person;
    person.name = "Bryant";
console.log(anotherPerson.name); // Bryant
    console.log(person.name); // Bryant
이 예제에선, person 객체를 anotherPerson으로 복사하였다. 그러나 person의 값이 실제 값이 아닌 참조로 저장되었기 때문에 person.name 프로퍼티를 "Bryant"로 변경하면 anotherPerson이 변경된다. person 프로퍼티 값의 실제 사본을 저장하지 않고 참조만 하기 때문이다.
객체 데이터 프로퍼티는 속성(attribute)이 있다
각 데이터 프로퍼티(데이터를 저장하는 객체 프로퍼티)는 이름-값 쌍과 (기본값이 true인) 세 가지 속성이 있다:
  • Configurable Attribute: 프로퍼티가 삭제되거나 변경될 수 있는지를 지정한다.
  • Enumerable: 프로퍼티가 for/in 루프에서 반환될 수 있는지를 지정한다.
  • Writable: 프로퍼티가 변경될 수 있는지를 지정한다.
ECMAScript 5는 위의 데이터 프로퍼티와 함께 접근자 프로퍼티를 명시하고 있음을 주목하라. 접근자 프로퍼티는 함수(getter와 setter)이다. 2월 15일에 이미 예정된 포스트에서 ECMAScript 5를 더 배울 것이다.
객체 만들기
객체를 만드는 두 가지 일반적인 방법이 있다:
1. 객체 리터럴
객체를 만드는 가장 일반적이고 가장 쉬운 방법은 객체 리터럴로 만드는 것이다:
// 객체 리터럴을 사용해서 빈 객체를 초기화시킨다.
var myBooks = {};
// 객체 리터럴을 사용해서 4개의 항목을 가진 객체
var mango = {
color: "yellow",
shape: "round",
sweetness: 8,
howSweetAmI: function () {
console.log("Hmm Hmm Good");
}
}
2. 객체 생성자(constructor)
두 번째 가장 일반적인 방법은 객체 생성자로 만드는 것이다. 생성자는 새 객체를 초기화하는 함수이며, 생성자를 호출하기 위해 새 키워드를 사용한다.
var mango =  new Object ();
mango.color = "yellow";
mango.shape= "round";
mango.sweetness = 8;
mango.howSweetAmI = function () {
console.log("Hmm Hmm Good");
}
객체의 프로퍼티 이름으로 "for"와 같은 몇몇 예약어를 사용할 수 있지만, 피하는 것이 현명하다.
객체는 숫자, 배열과 심지어 다른 객체를 포함하는 모든 데이터 타입을 수용할 수 있다.
객체를 만드는 실용적인 패턴
데이터를 저장하기 위해 여러분의 앱에서 한 번만 사용될 수도 있는 간단한 객체를 위해서, 위의 두 가지 방법으로 객체를 만드는데 충분하다.
과일과 각 과일에 대한 상세를 보여주는 앱을 상상해보라. 모든 과일은 다음과 같은 프로퍼티를 가진다: color, shape, sweetness, cost와 showName 함수. 새로운 과일 객체를 만들려고 할 때마다 다음 코드를 적는 것은 매우 지루하고 비생산적이다.
var mangoFruit = {
color: "yellow",
sweetness: 8,
fruitName: "Mango",
nativeToLand: ["South America", "Central America"],
showName: function () {
console.log("This is " + this.fruitName);
},
nativeTo: function () {
this.nativeToLand.forEach(function (eachCountry)  {
            console.log("Grown in:" + eachCountry);
        });
}
}
10개의 과일이 있다면, 같은 코드를 10번 추가해야 할 것이다. nativeTo 함수를 변경해야 한다면? 10개의 다른 장소에서 변경해야 한다. Now extrapolate this to adding objects for members on a website and suddenly you realized the manner in which we have created objects so far is not ideal objects that will have instances, particularly when developing large applications.
이런 반복적인 문제를 해결하기 위해, 소프트웨어 엔지니어들은 앱을 더 효율적이고 능률적으로 개발하기 위해 패턴(반복적이고 일상적인 작업을 위한 해법)을 발명했다.
객체를 만들기 위한 두 가지 일반적인 패턴이 있다. 여러분이 자바스크립트 제대로 배우기 과정을 하고 있다면 코드 아카데미의 레슨에서 첫 번째 패턴이 자주 사용되는 것을 본 적이 있을 것이다:
1. 객체 만들기 생성자 패턴
function Fruit (theColor, theSweetness, theFruitName, theNativeToLand) {
this.color = theColor;
    this.sweetness = theSweetness;
    this.fruitName = theFruitName;
    this.nativeToLand = theNativeToLand;
this.showName = function () {
        console.log("This is a " + this.fruitName);
    }
this.nativeTo = function () {
    this.nativeToLand.forEach(function (eachCountry)  {
       console.log("Grown in:" + eachCountry);
        });
    }
}
이 패턴을 적절히 사용하여, 모든 종류의 과일을 만드는 것은 매우 쉽다. 이를테면:
var mangoFruit = new Fruit ("Yellow", 8, "Mango", ["South America", "Central America", "West Africa"]);
mangoFruit.showName(); // Mango
mangoFruit.nativeTo();
// Grown in:South America
// Grown in:Central America
// Grown in:West Africa
var pineappleFruit = new Fruit ("Brown", 5, "Pineapple", ["United States"]);
pineappleFruit.showName(); // Pineapple
fruitName 함수를 변경해야 한다면, 한 곳에서만 하면 된다. 패턴은 한 개의 과일 함수와 상속을 이용해서 모든 과일의 모든 기능성과 특징을 캡슐화한다.
주의사항:
  • 상속 프로퍼티는 객체의 프로토타입 프로퍼티에 정의된다. 예로:
someObject.prototype.firstName = "rich";
  • 자신의 프로퍼티는 객체 그 자체에 직접 정의된다, 예로:
// 먼저 객체를 만든다:
var aMango = new Fruit ();
// 이제 aMango 객체에 직접 mangoSpice 프로퍼티를 정의한다.
// aMango 객체에 직접 mangoSpice 프로퍼티를 정의했기 때문에 상속된 프로퍼티가 아닌 aMango 자신의 프로퍼티이다.
aMango.mangoSpice = "some value";
  • 객체의 프로퍼티에 접근하기 위해서, object.property를 사용한다. 예로:
console.log(aMango.mangoSpice); // "some value"
  • 객체의 매서드를 적용하려면(invoke), object.method()를 사용한다. 예로:
// 먼저 메서드를 추가한다.
aMango.printStuff = function () {return "Printing";}
// 이제 printStuff 메서드를 적용할 수 있다:
aMango.printStuff ();
2. 객체 만들기 프로토타입 패턴
function Fruit () {
}
Fruit.prototype.color = "Yellow";
Fruit.prototype.sweetness = 7;
Fruit.prototype.fruitName = "Generic Fruit";
Fruit.prototype.nativeToLand = "USA";
Fruit.prototype.showName = function () {
console.log("This is a " + this.fruitName);
}
Fruit.prototype.nativeTo = function () {
            console.log("Grown in:" + this.nativeToLand);
}
그리고 아래는 이 프로토타입 패턴에 Fruit () 생성자를 호출하는 방법이다:
var mangoFruit = new Fruit ();
mangoFruit.showName(); //
mangoFruit.nativeTo();
// This is a Generic Fruit
// Grown in:USA
추가 읽기
이 두 가지 패턴의 완전한 논의와 각각의 동작법과 단점에 대한 철저한 설명을 위해, Professional JavaScript for Web Developers의 6장을 읽어라. 여러분은 자카스가 어떤 것을 최고로 추천하는지 배울 수 있을 것이다.(힌트: 위의 두 가지 다 아니다.)
객체 프로퍼티 접근하는 법
객체의 프로퍼티에 접근하는 두 가지 주요 방법은 점 표기법과 대괄호 표기법이다.
1. 점 표기법
// 지금까지의 예제에서 점 표기법을 사용해왔다. 여기 또 하나의 예제가 있다:
var book = {title: "Ways to Go", pages: 280, bookMark1:"Page 20"};
// 점 표기법을 사용해서 book 객체의 프로퍼티에 접근하려면, 이렇게 한다:
console.log (book.title); // Ways to Go
console.log (book.pages); // 280
2. 대괄호 표기법
// 대괄호 표기법으로 book 객체의 프로퍼티에 접근하려면, 이렇게 한다:
console.log (book["title"]); //Ways to Go
console.log (book["pages"]); // 280
//혹은, 변수로 프로퍼티 이름을 가질 수도 있다:
var bookTitle = "title";
console.log (book[bookTitle]); // Ways to Go
console.log (book["bookMark" + 1]); // Page 20
존재하지 않는 객체의 프로퍼티에 접근하면 undefined 결과가 나올 것이다.
고유와 상속 프로퍼티
객체는 상속 프로퍼티와 고유 프로퍼티를 가진다. 고유 프로퍼티는 객체에 정의되는 프로퍼티이고, 상속 프로퍼티는 프로토타입 객체로부터 상속된다.
객체에 프로퍼티(상속이던 고유이던)가 존재하는지를 알아내려면 연산자를 사용한다:
// schoolName이란 프로퍼티를 가진 새로운 school 객체를 만든다.
var school = {schoolName:"MIT"};
// schoolName school 객체의 고유 프로퍼티이므로 true를 출력한다.
console.log("schoolName" in school);  // true
// school 객체에 schoolType 프로퍼티가 정의되지 않았고, Object.prototype 프로토타입 객체로부터 schoolType 프로퍼티를 상속하지 않았기 때문에 false를 출력한다.
console.log("schoolType" in school);  // false
// school 객체가 Object.prototype으로부터 toString 메서드를 상속받았기 때문에 true를 출력한다.
console.log("toString" in school);  // true
hasOwnProperty
객체가 특정 프로퍼티를 고유 프로퍼티 중 하나로 가졌는지 알아내려면 hasOwnProperty 메서드를 사용한다. 이 메서드는 객체를 하나하나 열거하거나 상속이 아닌 고유 프로퍼티만을 원할 때 매우 유용하다.
// schoolName 프로퍼티를 갖는 새로운 school 객체를 만든다.
var school = {schoolName:"MIT"};
// schoolName school 객체의 고유 프로퍼티이므로 true를 출력한다.
console.log(school.hasOwnProperty ("schoolName"));  // true
// school 객체가 toString 메서드는 Object.prototype으로 상속되었으며, toString school 객체의 고유 프로퍼티가 아니므로 false를 출력한다.
console.log(school.hasOwnProperty ("toString"));  // false
객체 프로퍼티 접근하고 열거하기
열거할 수 있는 (고유와 상속) 프로퍼티를 접근하기 위해서는 for/in 루프나 일반 for 루프를 사용한다.
// schoolName, schoolAccredited, schoolLocation의 세 가지 고유 프로퍼티를 갖는 새로운 school 객체를 만든다.
var school = {schoolName:"MIT", schoolAccredited: true, schoolLocation:"Massachusetts"};
//school 객체의 프로퍼티를 접근하기 위해 for/in 루프를 사용하라.
for (var eachItem in school) {
console.log(eachItem); // schoolName, schoolAccredited, schoolLocation를 출력한다.
}
상속 프로퍼티 접근하기
Object.prototype에서 상속된 프로퍼티는 열거할 수 없으며, for/in 루프가 그것들을 보여주지 않는다. 그러나 열거할 수 있는 상속 프로퍼티는 for/in 루프 반복으로 보인다. 예로:
// school 객체의 프로퍼티를 접근하기 위해서 for/in 루프를 사용하라.
for (var eachItem in school) {
console.log(eachItem); // schoolName, schoolAccredited, schoolLocation를 출력한다.
}
// school 객체가 상속할 새로운 HigherLearning 함수를 만든다.
/* 사이드 노트: 날카로운 독자인 윌슨이 밑의 댓글에 정확하게 지적하였듯이, educationLevel 프로퍼티는 HigherLearning 생성자를 사용한 객체에 실제로 상속되지 않았다; 대신, educationLevel 프로퍼티는 HigherLearning 생성자를 사용한 각 객체에 새로운 프로퍼티로서 만들어졌다. 프로퍼티가 상속되지 않은 이유는 프로퍼티를 정의하기 위해 "this" 키워드를 사용하기 때문이다.
*/
function HigherLearning () {
this.educationLevel = "University";
}
// HigherLearning 생성자로 상속한다.
var school = new HigherLearning ();
school.schoolName = "MIT";
school.schoolAccredited = true;
school.schoolLocation = "Massachusetts";
// school 객체의 프로퍼티를 접근하기 위해 for/in 루프를 사용하라.
for (var eachItem in school) {
console.log(eachItem); // educationLevel, schoolName, schoolAccredited, schoolLocation를 출력한다.
}
마지막 예제에서, HigherLearning 함수로 정의된 educationLevel 프로퍼티가 school의 프로퍼티 중 하나로 열거된 것을 주목하라. educationLevel은 고유 프로퍼티가 아니며, 상속되었다.
객체의 프로토타입 속성과 프로토타입 프로퍼티
객체의 프로토타입 속성과 프로토타입 프로퍼티는 자바스크립트를 이해하기 위해 결정적으로 중요한 개념이다. 추가로 내 포스트 JavaScript Prototype in Plain, Detailed Language를 읽어라.
객체의 프로퍼티 삭제하기
객체로부터 프로퍼티를 삭제하려면, delete 연산자를 사용한다. 상속된 프로퍼티는 지울 수 없으며, configurable 속성으로 설정된 프로퍼티도 지울 수 없다. (프로퍼티가 정의되었던 곳인) 프로토타입 객체에서 상속된 프로퍼티를 지워야 한다. 또한, (var 키워드로 선언되었던) 전역 객체의 프로퍼티는 지울 수 없다.
delete 연산자는 삭제가 성공적이면 true를 반환한다. 그리고 놀랍게도 삭제할 프로퍼티가 존재하지 않거나 프로퍼티가 지워질 수 없어도(non-configurable이나 객체에 의해 소유되지 않은 등) 역시 true를 반환한다.
이러한 예를 설명하면:
var christmasList = {mike:"Book", jason:"sweater" }
delete christmasList.mike; // mike 프로퍼티를 지운다.
for (var people in christmasList) {
    console.log(people);
}
// jason만 출력한다.
// mike 프로퍼티는 지워졌다.
delete christmasList.toString; // true를 반환한다, 그러나 toString은 상속된 메서드이기 때문에 지워지지 않는다.
// 여기서 toString 메서드를 호출하면 잘 동작한다-지워지지 않았다.
christmasList.toString(); //"[object Object]"
// 프로퍼티가 그 인스턴스의 고유 프로퍼티라면 인스턴스의 프로퍼티를 지울 수 있다. 예로, educationLevel 프로퍼티는 인스턴스에 정의되었기 때문에 school 객체에서 educationLevel 프로퍼티를 지울 수 있다: HigherLearning 함수를 선언할 때 프로퍼티를 정의하기 위해 "this" 키워드를 사용하였다. HigherLearning 함수의 프로토타입에서 educationLevel 프로퍼티를 정의하지 않았다.
console.log(school.hasOwnProperty("educationLevel")); true
// educationLevel school에서 고유 프로퍼티이며, 지울 수 있다.
delete school.educationLevel; true
// educationLevel 프로퍼티는 school 인스턴스로부터 지워졌다.
console.log(school.educationLevel); undefined
// 그러나 HigherLearning 함수에 educationLevel 프로퍼티는 아직 존재한다.
var newSchool = new HigherLearning ();
console.log(newSchool.educationLevel); // University
// 다음의 educationLevel2 프로퍼티처럼 HigherLearning 함수의 프로토타입으로 정의했다면:
HigherLearning.prototype.educationLevel2 = "University 2";
// HigherLearning 인스턴스의 educationLevel2 프로퍼티는 고유 프로퍼티가 아니다.
// educationLevel2 프로퍼티는 school 인스턴스의 고유 프로퍼티가 아니다.
console.log(school.hasOwnProperty("educationLevel2")); false
console.log(school.educationLevel2); // University 2
// 상속된 educationLevel2 프로퍼티를 지워보자.
delete school.educationLevel2; true (앞에서 언급하였듯이 항상 true를 반환한다)
// 상속된 educationLevel2 프로퍼티는 지워지지 않는다.
console.log(school.educationLevel2); University 2
Serialize and Deserialize Objects
HTTP를 통해 객체를 전송하거나 문자열로 변환하기 위해서, 시리얼라이즈할(문자열로 변환할) 필요가 있을 것이다; JSON를 사용할 수 있다. 객체를 시리얼라이즈하기 하려면 함수를 문자열화하라. ECMAScript 5 전에는 JSON을 얻기 위해 (더글러스 크락포드의) 인기 있는 json2 라이브러리를 사용해야 했다는 것을 주목하라. 함수를 문자열화하는 것은 이제 ECMAScript 5에서는 표준이다.
객체를 디시리얼라이즈하기(문자열에서 객체로 변환하기) 위해서는, 같은 json2 라이브러리에서 JSON.parse 함수를 사용한다. 이 함수도 ECMAScript 5에서 표준이 되었다.
JSON.stringify 예제:
var christmasList = {mike:"Book", jason:"sweater", chelsea:"iPad" }
JSON.stringify (christmasList);
// 다음 문자열을 출력한다:
// "{"mike":"Book","jason":"sweater","chels":"iPad"}"
// 문자열화된 객체를 포매팅과 함께 출력하려면, 패러미터로 "null" "4"를 추가한다:
JSON.stringify (christmasList, null, 4);
/*
"{
    "mike": "Book",
    "jason": "sweater",
    "chels": "iPad"
}"
*/
// JSON.parse 예제 \\
// 다음은 JSON 문자열이다, 그래서 (christmasListStr.mike와 같이) 점 표기법으로 접근할 수 없다.
var christmasListStr = '{"mike":"Book","jason":"sweater","chels":"iPad"}';
// 객체로 변환하자.
var christmasListObj = JSON.parse (christmasListStr);
// 이제 객체이므로 점 표기법을 사용한다.
console.log(christmasListObj.mike); // Book
객체를 다루기 위한 ECMAScript 5 추가사항을 포함하여, 자바스크립트 객체를 좀 더 상세히 커버하기 위해서는 JavaScript: The Definitive Guide 6th Edition의 6장을 읽어라.
 
 
 
 
2016-03-10 SAD - 연세대학교 정보대학원 수업내용

 

우리가 알고 있는 시스템은 뭐가 있을까요? 수강신청? 정부도 시스템이고. 자동차도. 시스템 정의의 첫번째는 서브 시스템과 컨포넌트가 많다는 것. 몸도 시스템. 장기도 각각 시스템. 상호작용을 함. 생명체도 하나의 시스템. 살아 있는 것은 다 같다. 학교도 하나의 시스템. 체계적으로 구성되어 있는 것. 교학과도 하나의 체계가 있음. 목적은 뭐에요. 목적을 위해서 interact 하는 거에요. 행정체계. 수강신청 받는 것도 하나의 체계. 3가지는 꼭 있어야 함. 엔티티, 인터렉트, 목적.

시스템은 Boundary가 있어요. 시스템 안과 밖을 구분해주는 경계. 사람 몸의 바운더리는 피부. 연세대학교의 구성원은 어디까지인가. 이 경계가 조금 애매하죠. 여기에서 Boundary : 물리적, 추상적. 확실한 것은 고대 다니는 학생들은 연대 학생들이 아닌거죠. 그럼 이 Boundary의 역할은 뭐냐. Filtering 의 역할을 하죠. 바운더리가 있으면 외부에서 이렇게 리소스가 들어오죠. 이 경계해서 걷어내는 것이죠. 환경에서 들어오는 것을 다 받는게 아니라 경계를 통해 걸러내는 것이죠. 그리고 시스템을 통해 나가는 경우 변화가 일어나죠.

환경하고 상호작용 하는 경우 오픈 시스템. 상호작용 안하는 경우 closed 시스템. 예를 들어 북한. 은하계를 포함한 우주. 대부분 오픈 시스템이라 할 수 있겠다.

시스템의 중요한 특성을 이야기 할 수 있는데, Entropy에 대해 이야기 할 수 있죠. 시스템은 가만히 놔두면 죽는다는 거에요. 회사나 학교는 망하고 없어지겠죠. 한 30년? 없어지지 않으려면 어떻게 해야 하는가. Negative Entropy를 계속 줘야 해요. Negative Entropy를 계속 준다는 게 뭐에요? 컨트롤 하는거에요. 피드백을 주는거죠.
 

Output을 계속 분석하는 거에요. 개선을 하기 위해서. 그런 노력을 하지 않으면 변하는 거에요. Output의 수준을 평가해야해요. 이 과정에 문제가 생기면 죽는거에요. 학교 같은 경우. 사회에서 요구하는 인재를 배출해야해요. 어떻게 체크하죠? 취업률. 연봉. 고용 만족도 등. 학교 입장에서 학생 수를 늘리면 학생들의 수준이 떨어질 수 있음. 우리 필드에서 5년만 변하지 않고 있으면 도태될거에요.

어떤 현상의 수를 구하는 것이 Measure의 정의임.  만족도. 교수의 강의는 수준을 어떻게 측정할 수 있나요?

다른 과목 같은 경우, 90년대 사례를 쓰는 경우가 많아요. 우리 필드 수업은 힘들죠. Objective Measure 수단을 찾기가 힘들어요. 이걸 찾는게 중요하죠.

전체 시스템에서 Sensor에 해당하는 Objective Measure 수단을 찾는게 정말 중요해요. 인사고과 평가하는 것도 마찬가지. 객관적인 dimension으로 사전에 합의된 기준으로 평가 해야하는 거에요. 이거 굉장히 중요한거에요.

산출물이 정보 혹은 비즈니스 프로세싱이에요. 정보가 뭘까요. 정보하고 Raw data하고 뭐가 다를까요.

Data: Descriptions about facts. 사실에 대한 묘사.
정보는 기본적으로 데이터에요. 정제되고 조직된 목적을 위한.

모델은 현상을 추상화 시켜놓은 것이에요. 데이터 중에서 의사결정과 연관이 있는 것이 정보임. 유용성 Usefulness과 관련성 Relevance. 한남대교와 관련된 교통 정보는 나와 관련성이 있기 때문에 정보임. 연남대교와 관련된 Data는 raw data임. 그렇기 때문에 Refine과 processing이 중요한 것이 아님. 의사결정에 얼마나 연관되어 있는가가 가장 중요함.

내 시스템의 사용자들 혹은 고객이 그 데이터의 바다 중에서 어떤 데이터를 필요로 하냐. 그것들을 찾아내는 테크닉이 중요한 것. 

지식. Knowledge 란, (내가) 인증한 정보임. 내 마음속에 있는 것이 지식임. 지식이 그렇기 때문에 자신의 행동에 영향을 미치는 것임. 개인화된 정보. 정확하지 않을 수도 있음. Huber나 Nanaka에 있어서 지식은 entity(사람)에 의해 정당화된 믿음임. 지식에 관한 2번째 정의에 의하면 지식간의 포함관계가 달라질 수 있음. 이전까지는 정보중에 지식이 있다고 배웠지만, 2번째 정의에 의해서는 정보가 아닌 지식이 존재함. 지식으로 가는거면 전달할 수 있는거냐 없는거냐 이런 것도 있고. 어렵죠. 구분하기. 예를 들어 연구 능력의 경우는 전달하기 참 어려워요. 그래서 도제 제도라는게 있어요. 그렇게 되면 가능하죠. 테싯 날리지는 전달이 가능해요. 그게 바로 도제제도에요. 이게 날리지라는게 참 어려운 면이 있어요. 표현은 가능하지만 전달은 가능한 부분. 날리지 이론에 대해서는 Explicit knowledge 표현이 가능한 지식.(Information) 그리고 Tacit Knowledge 표현이 불가능한 지식도 있죠.

상호작용의 의미가 뭐냐. 하나가 바뀌면 다른 것들도 연쇄적으로 바뀐다는 것임. 예전에 프로젝트 들어갔던 부분 중에, 쿼리가 오래걸린다였는데. 백업을 안한대. (쉬는시간) 서로 영향을 주고 받기 때문에 시스템 분석가는 시스템 전체를 봐야 함. Systems Philosophy 조직 안에는 어떤 구성요소가 있을까요. 조직도 위의 그림처럼 볼 수도 있어요.

정보시스템이 바뀌는 것 때문에 조직내의 구성 요소가 바뀔수도 있음. 이런 것은 시험에 나올 수 있음. 기술 때문에 회사의 목적이나 Value가 바뀌는 경우.

 
아마존의 경우가 그렇죠. 크리스 마스 시즌에 정보시스템 용량 때문에 못팔았죠. 아마존이 크리스마스 시즌에 파는 매출 비중이 한 해 매출의 40%를 차지하죠. 그래서 아마존은 4억불을 매년 IT에 투자했죠. 매년 5천억을 그렇게 투자했죠. IT 기반이 단단해졌고 이걸 기반으로 AWS를 도입. 그리고 요즘 드론 배송하죠. 아마존은 이제 로봇해요. 창고에서 물류관리를 로봇이 해요. IT 때문에 이제 회사의 목적이 달라져요. 구글이 뭐하는 회사야? 검색? 안경도 한다고 하고 인공지능도 한다고 하고. 목적이 달라지는 거죠. IoT 시대에 빅데이터 시대의 Management는 어떻게 할 것인가.

Span of control : 예전에 매뉴얼로 컨트롤 할 수 있는 직원의 숫자가 Maximum 10~15명임. Manage 할 수 있는 능력이 한계가 있었음. 그런데 지금은 그게 아님. IoT와 빅데이터 시대에 달라진 것임.

94년에 쓰여진 논문에 제시된 개념. Middle-up-Down Management 스킬. IoT나 빅데이터 시대가 오면 M.C가 확 줄어들 것이다 라고 접근을 할 수도 있는데, 그렇지 않다는 거죠. Middle Level Manager 들의 역할이 점점 더 중요해질 것임.

중간관리자 레벨이 현실에서 Sense Making 할 수 있는 위치임.

IoT 시대에서는 팔고 끝이 아니죠. 때때로는 product은 공짜로 줄 수도 있죠. 정보를 분석해서 더 큰 Value를 줄 수 있죠. 거기서 Charge를 할 수도 있죠. 물건이 파는 대상이 아니게 되는거죠. 그렇게 되면 Customer Success Management 라는 조직이 생기겠죠? // 회사에 생겼습니다. 이번에. // 데이터가 리소스가 되는 것이죠. 데이터 전담 부서는 왜 없나. 가트너에서 2017년 정도에는 데이터 전담 조직이 생길 것이라고 말함. 전체적으로 Architecture가 달라지잖아요. Security가 뚫릴 수 있는 여지가 많아졌죠. 이것을 전담할 부서도 생길 것이다. 

이야기 하는 포인트가 뭐냐면, Technology가 변화하면서 그 외에 것들이 계속 변화한다는 것이죠. Informal Organization도 요즘에는 스마트 워크랑 스마트 오피스가 확대되고 있죠. 키스디에 있는 제자가 서울역에 있는 스마트 워크 센터에서 근무하더라고.
 

전체를 봐야 한다는 것임. Technology 때문에 서로 영향을 받아서 바뀐다는 것이죠. 그 중에 아주 중요한 것이 무엇이냐. interrelationship이 정말 중요한 거죠. 기존에 있던 M.C 관리자들은 어떻게 될까요. 기존에 있던 M.C 관리자들은 요즘 시대에 요구하는 Sense Making을 제대로 처리하기 어려워져요. 그래서 중간 관리자들이 저항을 할 수 있고, 저항을 하면서 시스템을 때때로 공격할 수도 있다. "(제대로 된 데이터 넣지 않고) 봐라 데이터 결과 잘 안나오지 않느냐" 이런식.

시스템 분석은 뭘하는가. 문제해결능력이 중요한 것이죠. 서울에 짜장면 집이 몇 개나 있느냐. 이세돌과 알파고는 누가 이길 것인가. 문제를 프레임화 하는 것이죠. 분석하고 종합하는 것이에요. 시스템 분석이라는 것은. 세상의 문제가 복잡하니까 단순화 시켜 나가는 것임. 주요 변수를 뽑아가지고 이것들을 집중적으로 보는 것이죠. 이것이 분석이에요. 정보시스템 분석에서 관련된 변수는 어떤 것일까요. 정보시스템의 문제는 무엇일까. 정보시스템이 Address 하는 문제는 뭘까.

정보처리 요구가 뭐냐를 결정하는 것임. 2가지. 하나는 데이터. 하나는 프로세스.

요구사항 분석은 위의 슬라이드에 나온 것들을 찾아내는 것.

나온 요구사항을 어떤 관점으로 볼 것인가. 크게 두 가지. 프로세스, 데이터 관점. (프로세스 모델링, 데이터 모델링)
Data, Process,
Event (Logic & Timing)

Alternative Generation and Selection은 이런 문제를 어떻게 해결할지에 대한 대안들. 직접 개발한 것인가. 패키지를 가져다가 쓸 것인가. 이런 것들을 하는 것이죠.

설계는 뭐에요. Technology Dependant 한 거에요. 코딩하는 사람들이 알아볼 수 있도록 기술 배경을 정하는 거죠.

부모의 기본키를 외래키로 갖게 되면 관계 표시가 되죠. 구체적으로 오라클이나 IBM DB에 표시를 해줘야 하는데. 그게 물리적 설계에요. 파일이 깨진다는 말이 뭐에요? 링이 끊어진다는 거죠. 자식에 있는 포인터가 다시 부모를 가리키면 링형이 되는거죠.

하드웨어 설계, 소프트웨어 설계, DB 설계, 프로세스 설계, 네트워크 설계. 이런게 시스템 분석 설계에요. 우리 수업에서는 네트워크 요구사항 뽑아내는거 까지만 해요. 두 서버 사이에 얼마만큼 자주 커뮤니케이션이 있어야 하는지 등을 결정하는 것이죠.

SDLC라는 것이 다음과 같은 절차를 거침. 

 

Feasibility가 차지하는측면이 큼.

경제적, 기술적, 운영적, 일정상, 법적, 정치적.
클라우드가 왜 클라우드? 구름 저편은 안보여서. 필요에 따라 쓰기만 하면 되는거지. 독일에서 법을 발표함. 독일에서 발생한 데이터는 독일에서 가져갈 수 없음. 데이터 센터를 독일에 만들라는 뜻. 클라우드 말고.

교재에 나오는 SDLC에요. 논리적인 개발 절차임. 그렇기 때문에 어떠한 시스템 개발이라도 이 절차를 따라가게 되어 있음.
 
정보공학 방법론 Information Engineering.
이게 어떻게 되어 있느냐.

정보 전략 계획.
전략 -> 분석 -> 설계 -> 구축.
프로세스(Activities), 데이터
 
정보전략계획 (Information Strategy Plan)

ISP를 하게 되면 프로세스 관점에서 나와야 하는 산출물이 있고 데이터 측면에서 나와야 하는 산출물이 있어요. 현업에서는 이렇게 따라가지 않는 경우가 많음. 시스템 내용은 안나오고 높은 레벨의 이야기만 나옴. 어떤 솔루션을 도입해야 하고, 견적에 대한 이야기만 함. PM의 감에 의해 견적을 이야기하더라. ㅋㅋ; 감리와 자문. Function Point 따져서 해야하는데, 대부분 그렇게 하고 있지 못하다.

ISP는 보면 사실 그대로 버리고, 단순히 비용 산정의 근거의 역할만 하고 있는 실정임. 저걸 안하면 이렇게 되는 것임. 사실 ISP가 제대로 되어야 실제 구현 단계에서 다시 처음부터 하는 그런 결과는 나타나지 않는 것임. ERP를 고치면 되요? 안되요.
 


2016-03-03 SAD - 연세대학교 정보대학원 수업내용

교재 7판
사전 리딩을 잘 읽어올 것. 절대 결석 하지 말 것.
15명 - 3명 1팀, 적으면 2명이 1팀.
 

기본적인 이야기만 하자고. 정보를 주고 업무를 대신 처리해주지. 이전에 수강신청하고 하면 종이로 쓰잖아요. 교학과에 내면 통계내고 그러잖아요. 수업시간표 내고 그러죠. 요새 시스템으로 하면 정보 시스템으로 처리가 되는 것이죠. 결과적으로 정보를 준다.

그런데 이 정보가. 회사에서 필요한 정보가. 경영 계층에 따라 필요한 정보의 계층이 다르다. 경영 계층의 삼각형. 밑이 운영 통제층. 경영 통제, 전략 통제. 어떻게 달라요? 김진동씨 이야기 처럼, 중요한 포인트 중에 하나인데, 중간관리자가 하는 일을 보면, 정보 취합해서 위로 올려주는 일을 많이 해요. 전달하는 역할을 많이 하죠. 중간 계층이. 부장들은 안그러죠. 비교를 해보죠. 이게 좀 안팔리네. 이런식. 아래쪽에서는 정말 정확해야해요. 몇 전 단위까지(원이 아니라) 정확해야 해요. 그런데 위쪽은 그렇지 않죠. 기간도 달라지고 금액 단위도 달라지고. 덜팔리면 프로모션을 하던가 조달을 하건 의사결정을 하겠지. 그 위에를 생각해봐. 전무 부회장 사장. 이런 사람들은 이걸 신경 안쓰죠. 매일 매일 매출이 어떤가 이런건 부장들이나 신경쓰는거지 임원들은 신경 안쓰죠. 임원들은 어떤 의사결정을 하죠? (여학생: 장기적인 의사결정을 할 것 같습니다.) 그렇죠. 신제품을 런칭할 것인가. 그런 것들을 하겠죠. 이런 사람들이 그럼 어떻게 다르죠. 지현? 이지현: 가공된 정도가 다를 것 같아요. 중간관리층은 주/월/분기 이렇게 보겠죠. 맨 위는 6개월, 1년, 10년 이렇게 보겠죠. 또 뭐가 다를까? (스마트폰을 쥐며) 뭐가 필요할까요. 향후 이후에 기술 추세에 대해 조사해서 알아봐. 시장 상황을 기술 추세도 봐야하고. 이런 것들이 기업 외부에서 오는 정보에요. 봐야 하는 기간도 굉장히 긴 거고. (오퍼레이션 쪽을 가르키며) 굉장히 정확하게 봐야 하고. 그렇죠. 각각의 경영계층에서 요구하는 정보의 특성이 다른거에요.

 
정보 시스템의 산물이 정보인데 정보가 다르다면 내부가 달라야겠지. 예를 들어서, 데이 투 데이 오퍼레이션을 해야 하는 계층. 데이터 베이스에서 검색을 하려고 하면 건별로 검색을 해요. 3/3일에 김동욱이라는 고객이 어떤 걸 샀느냐 보려면 딱 물고 봐야 해요. 시스템에서 아주 구체적으로 촥 하고 물고와야 해요. DB에서 어떤걸 봐야할까? 부장님들이. 특정 제품이 얼마나 팔렸는지에 대한 데이터. 쿼리가 들어갈 때 건드리는 레코드의 숫자가 달라져요. 그 많은 데이터를 물고와서 난도질 (slidation)을 하는데, 검색해야 하는 데이터의 양이 많아지면서 검색 쿼리의 양이 많아지죠. 중간 관리자가 봐야 하는 시스템의 특성하고 데이 투 데이로 보는 시스템의 특성하고 전혀 달라지죠. 아까 얘기한 것 중에 중요한 차이점이 임원들은 외부 데이터를 봐야 하죠. 네트웍으로 외부 데이터를 계속 검색해야 해요. 신규 제품을 출시하려면 특허DB나 이런 것을을 찾아봐야 하는 니즈가 있는 것이죠.

 
그래서 이 각각의 경영 계층의 필요한 정보가 달라요. 맨 밑에 있는 걸 거래처리 시스템 중간 관리자가 쓰는 걸 의사 지원 시스템, 전문가 시스템, 관리 정보 시스템이라고 하고, 임원들이 쓰는 걸 중역 정보 시스템이라고 하죠. 각각의 시스템이 다르죠. 우리가 배우는 것은 거래처리 시스템을 배웁니다. TPS 구체적으로 얘네들하고 어떻게 다른지에 대해 배워보자고요.

S - 임원진, T - 중간관리자, O - 현업직원
 

거래처리 시스템이 복잡한 이유가 뭘까요? // 김진동: 비즈니스가 복잡해졌기 때문에…. // 그래요. 옛날하고 달라요. 첫 번째로, 거래가 발생하면 독립적인게 아니라 관련된 기능이 너무 많아요.

 업무가 다 연관되어 있죠. 물건을 팔아도 현금 보유 정도가 늘어나야 해요. 우리 수강신청 어떻게 해요? 우리는 학점당 수업료가 다른가요? 미국은 달라요. 여긴 뭐 좋네요 ㅎㅎ. 미국 시스템 같은 경우 학생마다 크레딧 내는 시스템과 연동이 되어야 수강신청 시스템이 되는거죠. 복잡해 졌어요. 학교 등록금 카드로 할 수 있어요? 카드로 했는데 할부로 되면 어떻게 되는거죠? 그리고 요즘에 모바일로 가능한가요? 채널도 많아졌어요. 복잡해진거죠. 내부적으로 거래처리 시스템을 보면 굉장히 복잡합니다. 다른 거래 처리 시스템과 연결되어 있고, 그러니까 저게 의미하는 바가 무엇이냐면, 플래닝이 굉장히 중요하겠죠. 좀 더 자세하게 이야기 하자면, 분석이 무지무지하게 중요한 것이야. 시스템 개발하는 것 가지고 건물 짓거나 도시 짓는거에 비유를 많이하죠. 요즘 스마트 시티 관련해서 많이하죠 ㅎㅎ (지현 웃음 ㅎㅎ) 건물 하나 올린다고 생각해봐요. 기초공사하고 철근만 올리면 되요? 전기 배선도. 블루 프린트라고 하나? 청사진을 잘 그려야 해요. 잘 못하면 전기선이 벽을 뚫고 지나가요. ㅎㅎ 복잡하니까. 시스템을 개발하는게 굉장히 복잡한게 뭐냐면 필요한걸 미리미리 끄집어 내야 해요. 전기만 예를 들었지만, 배수도 있죠. 배수도 심각해요. 레귤레이션이 굉장히 많아요. 어떤 법적인 제약 조건에서 해야 한다. 이런 모든 걸 끌어낸 다음에 플래닝을 한 다음에 그 다음에 땅을 파야 해요. 예를 들어, 세일즈 트랜잭션이 발생했다. 그러면 세일즈와 관련된 시스템을 모두 가져다 놓고 개발을 해야 해요. 그런데 하다보니까 빠뜨렸어. 설계나 분석 단계에서. 그럼 결국 관련된 부분을 다 수정 해야 해. 집을 짓고나서 그걸 발견하면 부시고 새로 해야해요. 그런일이 발생하면 안되는데 그런 일이 발생해요. 진동씨. 외주주면 분쟁이 일어나요 안일어나요? 일어나죠. 버그가 생기면 버그가 잡아야죠. 어떤 일이 일어나면. 한진 그룹. 조중훈 회장님 지금 조양호 아버지이신데. 회장님 앞에서 시연을 하는거지. 그런데 안돌았어. 거래처리 시스템의 복잡성이 그런데서 나오는 거지. 그래서 방법론이라는 것이 필요한거야. 방법론이 뭐냐면, 시스템 개발 단계별로 해야 하는 것들의 템플릿이 있어. 산출물 까지 다 정해져 있어.

각 단계 이후에 어떻게 쓴다 이런 것 까지 다 나와 있는거죠. 그리고 이 작업을 할 때는 어떤 룰을 적용해야 하고 분석을 해야 하는지까지 다 나와있어. 이거 옛날에 배울 때는 2억이었어. 여러분들은 싸게 하는거지. ㅎㅎ.

정보 시스템을 구현하는 순서를 보면. 위와 같아요.
 

이 세계의 계층이 의사결정이 달라요. 굉장히 구조화 되어있죠.  구조화. 스트럭처드. 이 이야기를 잘 안쓰려고 하는데. 정형화 되어 있는. 프로그램화 할 수 있는. 여기서 말하는 것은 컴퓨터 프로그래밍은 아니에요. 공식화 할 수 있냐. 이런 의미로 쓰면 좋겠어요. 예를 들어서, Economic Order Qty(시간) 학교에서 생수 같은걸 주문 한다고 생각해봐요. 교학부에서는. 이걸 언제 몇 개를 주문할까요. 요즘에 농심라면, 신라면 많이 드시죠? 이마트 같은 곳에서 사람들이 신라면을 찾으러 왔어요. 그런데 없는거야. 이럴때 문제가 되는 거죠. 신라면을 언제 몇개를 주문을 할 거냐. 이것이 바로 ECO 모델이에요. 하나의 공식이에요. 재고 소진 속도. 얼마나 빨리 팔리는지. 하루에 몇 개나 팔리는지. 이런 속도가 있을거야. 구체적으로 주문하면 구체적으로 언제 가져오냐. 현재고가 사실 없어도 돼. 저거만 알면. 딜리버리 타임, 소진 속도만 알면. 저거는 뭐 공식이죠 공식. 룰로 딱 만들어가지고 현업 담당자가 저거 돌려가지고 주문만 하면 되는거야. 이런게 바로 구조화된 의사결정이죠. 세미-스트럭처드는 뭐에요? 뭐긴 뭐야 반구조화 되어 있는거죠 ㅎㅎ… 책에 나와 있는거 보면 타임지의 표지를 디자인하는 거죠. 이건 구조화 할 수 있어요? 이건 구조화가 안되는거죠. 감이라고 해야할까? 인사이트라고 해야하죠. 구조화 부분 부터 해볼까요. 어떤 정보가 필요할까요. 편의점 훼미리마트나 세븐 일레븐 같은 곳을 보면 하루에 제품을 얼마나 많이 바꾸는지 아세요? 아침에 많이 팔리는 물건 점심에 많이 팔리는 물건 같은 것들을 진열을 계속 바꿔요. 그쵸? 점심밥 먹는 것도 사람들이 날씨에 따라 달라져요. 그러니까 보면 우선 통계적으로 봐서 어떤 시간대에 어떤 물건이 많이 팔리는지 봐야하죠. 그 다음에 봐야 하는 게 뭐죠. 지역특성. 인구적 특성(데모그라피적), 날씨. 이런거 봐야하죠. 본사에서 이런 것들을 종합해서 가이드라인을 줘요. 그럼 점장을 그것들을 보고 참고해서 의사결정을 해요. 예를 들어서 본사는 광화문점에서 그 날 데모가 있을 것인지에 대해 정확히 몰라요. 점장은 그걸 알죠. 이런게 세미-스트럭쳐드 의사결정이죠. 눈 높이에 있는 매대가 1등석. 거기에다 제일 popular한 브랜드를 놓아야 하죠. 거기다가 놓아야 하죠. 영업 사원들이 매장에 방문해서 하는 게 진열 바꾸는 거해요. 자기네 물건을 1등석에 놓는거죠.
 

경영자의 의사결정을 지원해 주는거죠. 이런걸 지원해주려면 시스템 구성 요소중에 뭐가 있어야 겠어요? 굉장히 다양한 통계 패키지가 들어가야겠죠? 통계 패키지는 엄청나게 많아요 무빙 애버리지 모델 등등. 그 안에 모델이 많이 들어가요. 데이터베이스와 같은 개념인데, 그것들을 뭐라고 하냐면 모델 베이스라고 해요. 데이터 베이스는 들어봤죠? 모델 베이스라고 해요. Data_Base, Model_Base. 데이터 베이스는 DB 깡통이에요. 그 안을 들여다 보면 그 안에 데이터가 있어요. 데이터 베이스를 가져다 쓰려고 하면, 소프트웨어가 있어요. DBMS (Database Management Systems) 프로덕이 많아요. DDL 데이터 데피니션 랭귀지. 이런거 하죠. 길이정해주고 타입 정해주고. 파일도 있고. 이런 것들 디파인 하는 것이 DDL이에요. 이안에 많아요. 리커버리 하는 것도 있고. 얘를 종합적으로 관리하게 해주는 것이 DBMS야. 이거랑 똑같은게 MBMS가 있어요. 모델 베이스 메니지먼트 시스템. 모델을 검색하게 해주고. 두 개를 붙일 수 있게 해주고. 모델을 개발할 수 있게 해주고. 하는 것이 MBMS야.

DSS의 가장 큰 특징은 MBMS 기반이라는 거에요. 모델 베이스. 이게 가장 큰 특징이에요. 통계 패키지 돌려보셨어요? 통계 패키지로만은 안되요. 결국은 DB를 물고 돌려야 해요. 1년치 통계 데이터 누적이 되면 규모가 어떻게 될까. 파일의 크기가 어떻게 될까. 증권거래소 데일리 트랜잭션이 어느정도나 되요? 엄청나요. 그것 물고 돌리는 거에요. 1년치 누적된 데이터만 가지고 통계 패키지를 돌리자 그거에요. 미래 예측하는. 잘 모르겠지만 오래걸리겠지. 이거 도는 동안은 다른 사람은 못써요. 그러니까 얘는요. 시스템을 따로 써야 해요. 거래 처리하는 시스템하고 완전 따로 써야 해요. 그리고 DB 구조가 달라야 해요. 제일 크게 다른게 뭐냐면 이 DB구조는 업데이트 인서트 델리트가 없어요. 10년치 데이터를 물고와서 수정을 해봐. 그러면 시스템 리소스는 다 나가는거야. 그래서 얘는요 기본적으로 Read-Only에요. 그러면 새로 나오는 데이터는 어떻게 해요? 갖다가 붙여요. 맨 끝에다가. Append 하는거죠. DSS에서 쓰는게 데이터 웨어하우스에요. 그럼 데이터 웨어하우스가 빅데이터에요? 그건 또 아니에요. 거래처리 시스템과 의사결정 지원 시스템이 다르죠? 모델 베이스도 있고 데이터 웨어하우스도 다르고. TPS 만드는 절차랑 DSS 만드는 절차가 달라야겠죠? 달라요.

전문가 시스템이 뭐에요? // 시스코 학생분: 외부 데이터를 가져오고 내부 데이터를 분석해서 알고리즘이나 추세를 가지고 초점을 맞춰서 결론을 내는거. // 전문가 직업 뭐뭐 있어요? 문제가 생기면 자기네 들이 노하우가 있어. 그 노하우를 시스템화 해놓은게 전문가 시스템이야. 의사들이 하는게 뭐에요. 검사 결과를 해석하는 거에요. 그게 전문성이라는 거에요. 검사결과의 범위를 정해놓고 어떤 병을 의심해봐라 하는게 전문가 시스템이에요. 세무사의 전문가 시스템은 뭐에요. 세금계산하는거에요. 세법에 근거해서. 세법을 보면 어떻게 되어 있어요? 기본적으로 소득이 얼마면 세율이 몇 % 이런식으로 되어있죠. 세무신고 해봤죠? 그런거에요. 부양가족이 몇 명이면 곱하기 얼마해서 어디에서 빼라. 소득공제하는 상품에 가입되어 있으면 얼마를 빼줘라. 그것들을 뭐라고 하는가. 전문가의 전문성을 시스템화 한게 Knowledge Base에요. 룰베이스. 거의 대부분 되요. if조건 해가지고 하면 거의 다 되요. 전문가의 전문성이라는걸. 변호사의 전문성이라는 건 뭐에요. 법이에요. 변호사가 또 뭐하는지 아세요? 판례 찾아요. 주니어 변호사 되면 하루종일 판례만 찾아요. 그렇죠? 우리 분야에서 한창 이야기 나오는 것이 미래에 없어질 직업. 엑스퍼트 시스템도 AI의 한 분야에요. 로봇은 저걸 가지고 적용을 하는 거지. 없어질 직업들 대표적인게 변호사에요. 수요가 확 줄어들 것이에요. 이거 이제 로봇이 할 것이죠. 세무사는 이미. 국세청 사이트 들어가서 해보세요. 지가 다해요. 연말정산도 엑스퍼트 시스템의 하나에요. 의사. 의사도 수요가 많이 줄거에요. 의사의 전문성이라는 게 결국 전부 검사결과 해석하는 것이에요. 데이터는 있어야지. 여기서는 엔진이라고 해. 엑스퍼트 시스템의 엔진은 뭐에요? Knowledge Base를 관리하는 거에요. 그런데. 엑스퍼트 시스템을 개발하는데 제일 중요한 것은 무엇이냐.

전문가의 전문성을 어떻게 끄집어 내야 할 것인가. 전문가의 전문성을 끄집어 낼 수 없는 부분이 있어요. 그게 뭘까. 디자이너. 같이 전문가의 전문성을 어떻게 끄집어 내야 하는거. 이런게 어려운 분야는 당분간 직업이 없어지진 않을거에요. 이게 개발 절차에요. 제일 어려운 부분이 Knowledge Acquisition 이런 부분이죠. 보시면은. DSS가 나름 특징이 있고, TPS 특징하고 또 달라. Expert System은 또 달라. 각각 포인트가 있고.

엑스퍼트 시스템을 보면 질문을 계속해요. 계속 물어봐. 시리즈 오브 퀘스천. 엑스퍼트 시스템과 DSS는 근본적인 차이가 있어요. 엑스퍼트 시스템은 답을 줘요. 세금 엑스퍼트 시스템은 네가 금년에 낼 세금이 얼마다 라고 딱 나와. 병원에서 쓰는 엑스퍼트 시스템에서는 환자의 병명이 나와요. DSS에서는 답을 주는게 아니라 의사결정에 도움을 주는 정보를 줘요. 엑스퍼트 시스템의 용도는 뭘까요. 실제로 쓰거나 트레이닝 목적으로 써요. 각각의 시스템 마다 개발하는 절차가 다르고 내용도 다르죠. 근본적인 다름의 이유가 뭐야? // 엔드유저가 다르다. // 각 경영 계층 마다 의사결정의 속성이 다르다. 그래서 우리가 하는 것은 TPS를 개발하는 절차를 배운다.

 
TPS 시스템의 특성이 뭐죠? 정확해야 하고 빨라야해. 복잡해.
TPS에서 DSS로 넘어가는 연결고리는 어떻게 해야하나. DSS의 DB는 다르다고 했죠. 1주일에 한 번이나 2주일에 한 번 정도 데이터를 가져다 줘야 최신 자료로 돌리겠죠? TPS가 ERP인데. SAP에서. 비즈니스 웨어하우스라는게 있어요. BI라고 비즈니스 인텔리전스. 이게 데이터 웨어하우스인데. 이런 과정이 있어요. TPS 끼리의 관계는 시스템 안에서 통합을 해서 지들끼리 연결을 해줘. // 모델 베이스는 DB에서 뷰를 만들어서 올리는 거랑 비슷하다고 볼 수 있나요? // 모델 만들어서 불러다가 쓸 수 있어요. KMS는 잘 안되고 있는게, 컨택스트가 다르기 때문에 잘 안되요. KMS는 디렉토리에요. 내가 알고 있는 분야의 태깅 정도. 어떤 문제에 대해서 문제가 있으면 누가 알고 있다. 이정도. 태깅이라고 해야할까. 날리지를 바로 찾는다. 이런 개념보다는 이런 정보는 누구에게 물어보면 된다. 이정도가 가장 효과가 크다. SI업체에서 제안서를 공유하는 시스템을 만들었는데, 이게 잘 안돼. 엑스퍼트 시스템 같은 경우에 구조화 여부가 가장 커요. KMS와 날리지 베이스의 가장 큰 차이점은 구조화 할 수 없는 걸 KMS에서 담으려고 한다는 거에요. 연구라는게 가장 큰 게 연구 주제를 잡아야 하는거에요. 신삥 박사들은 그걸 잘 못잡아요. 이건 설명이 안되는 부분이에요. 이런게 있어요. 테싯 날리지 부분인데. 엑스플로싯 날리지는 언어로 표현이 가능해요. 테싯은 언어로 표현이 안되는 부분이에요. 타자가 공을 잘 치는 것이 룰로 만들어지나? 거의 본능적으로 치는 것이지. // KMS가 결과적으로는 실무에서 구축해보면 잘만들어진 FAQ정도 밖에 안되더라고요. // 유형화가 가능해도 보안 전문가 시스템을 예를 들면, 새로운 유형이 계속 나오면 그것도 문제가 된다.

시스템 분석가라는 잡 타이틀이 있어요. 시스템 분석가가 뭘 하는거에요? 비즈니스 문제를 컴퓨터로 푸는 사람들이야. 정보 시스템으로 비즈니스 문제를 풀려고 하는 사람들이 시스템 분석가에요. 시스템 분석 설계는 뭐냐. 비즈니스 시스템을 분석하고 정보 시스템을 디자인 하는거에요. 비즈니스 문제를 분석하는 거에요. 먼저. 예를 들어, UI가 불편해요. 프로그램이 느려요. 이런건 시스템 문제에요. 비즈니스 문제가 뭐에요. 우리학교에 우수한 학생이 안와요. 교수들이 연구 실적이 떨어져요. 이런게 비즈니스 문제에요. 비즈니스 문제를 연구하는 거에요. 이런 비즈니스 문제에 대해 시스템적인 솔루션을 주는 거에요. 정보대학원에 사람들이 안와요. 왜 그럴까. 얼마나 좋은지 모르니까. 커리큘럼이 옛날 것이다. 이걸 어떻게 해결할 것인가. 예를 들어, 학생들이 원하는 정보를 추려야죠. 평균 졸업생 연봉, 평균 취업률, 입학생 백그라운드. 이런 정보들을 어디에 뿌릴 것인지. 채널까지 정해줘야 하죠.

이 과정에서 시스템이 할 일이 있죠. 그 문제를 정보 시스템으로 푸는게 시스템 분석 설계에요. 그래서 첫 번째가 비즈니스 시스템 분석이에요. 그리고 나서 정보 시스템 설계를 하는 것이죠. 구조적인 접근이 중요하죠. 왜 중요해요? 복잡하니까. 우리 시스템 하나 구축하면 엔티티 숫자로 이야기하면 base entity가 거의 800개에요 작은 기업이. 여기에서 파생되는거면 더 크죠. 그래서 구조적인 접근이 필요하죠.

시스템에서 가장 중요한게 데이터랑 프로세스.

우리가 프로세스 모델링과 데이터 모델링을 할 것인데, 이게 헷갈려요. 데이터는 독립적이에요. 나홀로 살아. 그런데 문제는 뭐냐. 데이터는 프로세스가 움직여 주지 않으면 아무것도 못해. 그러니까 프로세스가 데이터를 사용하는 거에요. 프로세스가 데이터를 사용하지 않으면 스스로 아무것도 못한다. 아시겠죠. 예를 들어, 매일매일 발생하는 거래 DB가 있어요. 그럼 이놈이 DB 깡통에 들어가 앉으려면 프로그램이 돌아야 DB에 저장이 되요. DB에 저장이 되어 있는 걸 수정하려면 그것도 프로그램이 하는 거에요. 프로그램의 도움이 없으면 저 혼자 뭘 못해. 프로세스와 데이터의 관계는 뭐냐. 프로세스가 데이터를 써요. 어떻게 쓰냐. CRUD (Create, Read, Update, Delete) 라고 해요. 저걸 모르면 이과목이 패스가 안되요 ㅎㅎ 굉장히 중요한거에요. 프로세스가 데이터를 써요 어떻게 써요? 넷 중에 하나로요. 그렇죠.

DB 개발과정은 이래요. ER 만들었죠? 처음에 개념 모델을 만들어요. Conceptual Schema에요 스키마는 뷰에요. -> 논리모델을 만들죠. Logical Schema -> 물리 모델 Physical Schema
그래서 이런 과정을 쭉 따라 가서 DB가 만들어지죠.

프로그램들이 중앙 DB를 같이 쓰는거에요. 함께. 그래서 관련된 시스템들 사이의 연관관계를 어떻게 지어주냐. 센트럴 DB를 통해서 하는거에요. 개념적으로 공통된 DB를 하나 만들어 놓는거에요. 업무가 생기면 여기다가 다 갖다가 써요. 그리고 얘를 공유하는 거에요.

이 과목은 프로세스에 중점을 두고 DB에 대해서도 해요.
 

시스템 분석을 잘하려면 결국 해당 비즈니스에 대해 잘 알아야 해요. 은행 시스템은 은행 업무를 잘 알아야 해요. 문제 해결 능력이 정말 좋아야 해요. 시스템 분석가는 사람간 관계를 잘 맺어야 해요. 시스템 분석가는 참 어려워요. 현업하고 일하면서 컴퓨터 프로그래밍 하는 사람들하고도 일해야 해요.

이런 스킬을 얻으려면 해봐야 해요. 그래서 숙제를 내주는거죠. ㅎㅎㅎㅎㅎㅎㅎㅎㅎ 숙제도 해보고 프로젝트도 해보고 시험도 해봐야 해요. 숙제를 채점해보면 집에서 집사람이 왠 그림밖에 없냐고 해요. //김진동: 개념모델. 이런 이야기 해주셨는데 수업시간에 나올 이야기죠?
 



2016 08-11 아산서원 나눔특강 - 빅데이터 분석을 통한 조혈모세포 기증에 대한 대중 인식과 실제

  1. 1. 나눔특강
  2. 2. 1.도입
  3. 3. 바늘 들어가는 거 무서워서 헌혈할 때 못보는 너무나 평범한 사람의 조혈모 세포 기증기 조혈모세포 기증 하는 모습 기증 이 후 감사패  1주일이라는 시간과 아픔, 각종 우려와 잘못된 인식, 5개월간의 금주 끝에 무사히 조혈모 세포 기증을 마침  어떤 과정을 거쳐서 결심하게 되었는지 나누기 위해 이 자리에 섬.
  4. 4. 2.조혈모세포기증
  5. 5. 빅데이터란, 기존 Data Analytics를 실시간/결과 도출/구체적 운영 제안 범위로 까지 확장시킨 것.  자료의 활용적 측면에서도 2차 자료(Secondary Data)를 활용하는 경우가 많음  애초에 분석을 위해 누적된 데이터가 아니기 때문에 객관성을 보완.  “검색할 때 사람들은 거짓말을 하지 않는다” *장영재(2012), DBR, “엄청난 정보로 새 패러다임을 열다. 구글의 무인자동차 처럼” **정재화(2012). "시작하세요! 하둡 프로그래밍 기초부터 실무까지 하둡의 모든 것." 빅데이터를 활용한 대중 인식파악 예시**빅데이터 분석과 일반 데이터 분석간 차이* The United States (is vs are)
  6. 6. 일반적으로 ‘백혈병’ 이라고 하면 ‘골수기증’을 흔하게 떠올리기 마련.  <너는 내 운명> 에서는 친모와 시어머니가 동시에 백혈병에 걸리는 데, 여주인공은 둘 중 선택을 해야 하는 상황(실제로는 매우 희박함).  미디어 속 ‘골수 기증’은 매우 고통스럽고 후유증도 심각한 것으로 묘사되는 경향이 있음. 사진출처: KBS 비현실적인 골수 조직 일치도‘백혈병’과 ‘골수기증’이 주요 갈등 요소
  7. 7. 미디어의 영향으로 ‘조혈모 세포’에 대한 인식은 현재 ‘골수’에 대한 인식에 비해 5배나 낮은 상황  R을 활용한 드라마 ‘너는 내운명’과 ‘골수’, ‘조혈모세포’ 간의 다중회귀분석 실시  Model의 F-statistic P-value가 𝟎. 𝟎𝟎𝟎𝟎𝟗𝟑∗∗∗ 으로 기준 값인 0.001보다 작아 매우 유의한 결과  모델의 각 경로의 P 검정 결과, 골수는 𝟎. 𝟎𝟎𝟕∗∗ 로 유의한 것으로 조혈모 세포는 𝟎. 𝟎𝟏𝟏∗ 로 다소 유의한 것으로 나타남. 출처: Google Trend (2016.08) 조회 결과 참고: 서민구(2014), 길벗, “R을 이용한 데이터 처리&분석 실무” 2008. 8월 드라마 <너는 내운명> 관심도 1차 최고점 2010. 9월 드라마 <너는 내운명> 관심도 2차 고점 2011. 7월 드라마 <너는 내운명> 관심도 3차 고점 2008. 5월 드라마 <너는 내운명> 방영시작 Adjusted 𝑹 𝟐=0.11 평균 드라마 시청률 30.8% 시청률 감안 𝑹 𝟐=0.34 골수 관심도 – 조혈모세포 관심도 = 40 시청률 감안 𝑹 𝟐 값이 관심도 차이를 근접히 반영
  8. 8. ‘골수’와 ‘조혈모세포’, ‘백혈병’에 대한 SNS 분석 결과 기증에 대한 막연한 두려움이 주로 드러남  2016-07-09 ~ 2016-08-09간 수집된 트위터와 네이버, 다음 블로그의 12,603건 분석 결과  ‘정치용어’, ‘골수팬’ 등 ‘기증’과 연관성이 떨어지는 탐색어를 정제 하였음. 데이터 출처: 다음소프트(2016), 소셜 매트릭스, “탐색어 추이”, 기간: 2016-07-09 ~ 2016-08-09 SNS 탐색어 맵 분석 결과 골수 닳다 부작용 심하다무서운 반대 하다 조혈모 세포 좋지않다 & 해로운 부작용 & 걱정 힘들다 부족한 무서운 & 무섭다 고통 & 공포 슬프다 백혈병 부작용 싫어 하다 충격 & 울다 위험한 & 위험 어렵다 & 어려운 고통 & 힘들다 발암 물질
  9. 9. 이에 따른 골수기증 및 조혈모세포 기증에 대한 괴담도 퍼지기 시작.  다른 장기마냥 골수를 주면 나는 없어진다. (거짓)  골수가 실제 환자에게 전해지는 것이 아니라 제약회사에 팔려진다. (거짓)  조혈모세포 재단이 막대한 수술비로 이익을 보고 있다 (거짓) 출처: JTBC (2016), 팩트체크, “혈액재고 비상…헌혈에 대한 오해와 진실”, https://www.youtube.com/watch?v=tzaC7yhjN_0
  10. 10. 조혈모세포 이식 수술의 의료수가는 국내의 경우 법으로 정해져 있으며, 의료보험시 매우 저렴한편  국내의 경우, 환자 부담금이 의료보험시 750~1,500만원선 (보건복지부, 2014)  미국의 경우, 가족외 타인에 의한 Bone Marrow (allogeneic) 이식 수술 비용은 $925,000 한 화로 약 10억원 이상(NFT, 2014) 출처: 보건복지부(2014), 보도자료, “비승인 조혈모세포이식 환자 최고 1,500만원 부담 감소” NFT(2014) U.S. organ and tissue transplants Milliman Research Report. http://www.transplants.org/faq/how-much-does-transplant-cost
  11. 11. 국가별 장기기증 현황 및 국내 기피 이유조혈모 세포 기증희망자 막연한 두려움과 문화적 요소로 인해 기증등록자, 기증동의율 모두 열악한 상황  인구의 1%인 50만명까지 필요한 상황이나 0.56%인 29만명에 그치고 있다(대한적십자사, 2015). 독일의 경우 인구의 5.7%인 460만명이나 등록되어 있음(질병관리본부, 2013).  타인간 조직 일치 확률은 1/20,000 로 국내 이식 대기자 현황에 비해 턱없이 부족한 형편 출처: 질병관리본부(2013), 희망의씨앗 정책매거진, Vol 6 대한적집사자(2015), 조혈모세포 기증 소개 및 현황, https://www.bloodinfo.net/stemcelldonation_intro.do
  12. 12. 질환별 이식현황기증방법별 현황 골수기증은 조혈모세포 기증 방법 중 하나로, 최근에는 말초혈 조혈모세포 기증이 주로 이루어짐  조혈모세포이식은 환자의 골수를 고용량의 항암제, 방사선으로 제거한 다음, 건강한 조혈모세포 를 넣어주어 다시 골수를 제건하는 방법. 조혈모세포는 적혈구, 백혈구, 혈소판을 만드는 어미세 포로 뼈 속의 골수에 많이 있는데, 말초혈액과 제대혈에도 존재함(삼성서울병원, 2016).
  13. 13. 약 1~2주 정도에 걸쳐서 기증은 이루어지며, 수술 2주전에는 취소가 불가능하니 신중한 결정필요. 03-1. 기증자: 입원전까지 금주 등 건강관리 03-2. 기증자: 1주일간 6대의 그라신 투여, 사람에 따라 통증 편차 심함. 진통제 제공. 03-3. 기증자: 중심정맥관 삽입술/골수 기증 진행할지 결정. 04-1. 수혜자: 타인의 조혈모세포를 이식받기 위해 수술 2주전에 방사선 전처리함. 이 때, 기증을 취소하면 환자는 100% 사망함. 신중히 결정해야 하는 이유. 05-1. 기증자: 2주뒤 혈액검사 결과가 정상으로 나오면, 음주도 가능. 05-2. 수혜자: 신생아들에게 실시하는 예방접종 실시, 면역 체계 재구축. 1년 생존시 95% 완치 05-3. 수혜자: 혈액형이 기증자를 따라 변화하기 시작. 5년 생존시 완치 판정
  14. 14. 아무리 확률이 낮아도… 의료사고 및 사망까지 고려할 수도 있는 상황으로 부터 오는 두려움  스카이 다이빙에는 기쁘게 나서던 자신이 어째서 망설이는지에 대한 의문  사고가 나더라도 별도의 보험으로 보호가 되고, 병원에서도 신속히 조치해주는 것을 약속  혹여나 잘못되더라도 웰다잉이 아닐는지… 출처: MedicalTimes(2015), “중심정맥관 삽입술 시 대량 출혈, 의료진 책임 20%”, http://www.medicaltimes.com/News/1101370 스카이 다이빙에 앞선 신체포기각서중심정맥관 삽입으로 인한 사망사고
  15. 15. 꼭 반드시 내가 해야하는 일과 그렇지 않아도 되는 일이 있음. 나눔 실천에도 마찬가지  ‘조혈모 세포’ 기증은 다른 누군가가 대체 불가능한 속성을 지니고 있음 출처: Rainforest Alliance (2012), Follow the Frog, URL: https://www.youtube.com/watch?v=3iIkOi3srLo
  16. 16. 수혜자가 사회에 해를 끼치면 어떻게 하나?  수혜자는 성인 백혈병 여성이었기 때문에, 골수 기증을 받은 성인 125명을 대상으로 18년간 이 루어진 삶의 질 추적연구를 참고하였음.  “74% of long-term survivors of bone marrow transplanation reported their current QOL was the same or better than before transplantation, 80% rated their current health status and QOL as good to excellent, and 88% said the benefits of transplantation outweighed the side effects.”*  대부분의 환자가 삶의 질이 나아진 것을 확인할 수 있었음 *출처: Bush, N. E., Haberman, M., Donaldson, G., & Sullivan, K. M. (1995). Quality of life of 125 adults surviving 6–18 years after bone marrow transplantation. Social science & medicine, 40(4), 479-490.
  17. 17. 수혜자에게 코디네이터를 통해 전달한 편지와 서적 사회를 위한 일이 수혜자의 일탈로 인해 사회에 해가 되지 않도록 당부.  기증자의 개인정보는 제거 했으나, 희생한 일들을 강조하여 일탈하지 않도록 의무감 부여.  석사졸업시험 연기, 5개월간의 금주, 부모님과의 갈등 등.  사회에 도움이 되는 일은 선택사항으로 명시
  18. 18. 3.서원생으로의자각과사회적책임
  19. 19. 함께 면접을 봤으나 합격하지 못한 여학생은 서럽게 한참을 울었다…  제가 앉아 있던 서원의 그 자리가 월등히 뛰어나서 앉아 있던 것이 절대 아니라 생각함.  운이 좋았을 수도 있고, 면접과 시험날 붙을 만한 사람의 컨디션이 안좋았을 수도.  설사 모든게 완벽했다 하더라도 떨어진 친구들이 납득할만 해야한다고 생각함.
  20. 20. 사회에서 길러진 사람이 아니면, 본전 생각이 날 수 밖에 없는 사회  개천에서 용이 나도 개천을 돌아보지 않는 사회.  너무도 힘들게 그 자리에 가서 본전 생각이 날 수 밖에 없음. SKY 진학률과 중식지원 받는 학생 비율 관계 *출처: JTBC (2012), '개천서 용 날 수 없나' SKY진학률 비교해보니, http://news.jtbc.joins.com/article/article.aspx?news_id=NB10106361
  21. 21. 4.큰변화를이끌어낼수있는작은실천들
  22. 22. 당신이 두려움을 이기면, 누군가는 죽음을 이깁니다.  가까운 헌혈장소를 방문하여 상담 후 '조혈모세포 기증희망자 등록 신청서'를 작성한 후 조직적 합성항원형 검사를 위한 혈액검체 5ml를 채혈하면 가능.  가능 기관: 대한적십자사, 가톨릭조혈모세포은행, 한국조혈모세포은행협회, 생명나눔실천본부, 한마음한몸운동본부 출처: 대한적십자사(2016), “기증희망 등록방법 및 유의사항” https://www.bloodinfo.net/stemcelldonation_method.do 유의 사항기증 희망 등록기준 만 18세 이상에서 40세 미만의 건강한 분들 1. HIV 감염 또는 에이즈(AIDS) 2. 조절이 안 되거나 입원이 필요한 정도의 중증의 천식 3. 각종 악성종양 4. 투약이 필요한 당뇨병 5. 지난 1년 안에 2회 이상의 발작 경험이 있는 간질 6. 심장발작(heart attack), 심혈관 우회로 수술, 기타 심장 병 7. 간 질환, 간염, 성병, 결핵 8. 빈혈, 고혈압, 저혈압 9. 정신질환, 지적장애인 다만, 정신과전문의가 본인 동의능력을 갖춘 것으로 인 정하는 사람은 그러하지 아니한다. 10. 저체중(남:50kg 미만, 여: 45kg 미만) 1, 2, 3, 4, 6, 8, 9번 항목은 현재질병이 없고 과거 어 느시점에서도 기왕력이 없어야함 5, 7번 항목은 현재질병이 없고 과거 1년간 기왕력이 없 어야함. 10번 항목은 현재 없으면 됨. 조혈모세포 이식은 환자와 그 가족에게는 생명의 희망입 니다. 기증희망 등록 후 연락이 안 되거나, 가족반대 또는 본인 의 기증거부로 인해 이식이 불가능하게 될 경우 이식을 기 다려온 환자들 에게 더 큰 상처가 됩니다. 기증희망 등록을 하고자 하시는 경우 본인의 의사를 가족 에게 알리시고, 기증에 대한 정확한 상담을 통한 결정을 부탁드립니다. 그리하여 10년…20년 후 조직적합성항원형이 일치하는 환자분이 나타났다는 연락을 받으셨을 때 그 약속이 지켜 질 수 있기를 부탁드립니다. 환자분이 나타났다는 연락을 받을 수 있도록 개인정보 수정을 꼭 해주시기 바랍니다.
  23. 23. 뇌사시 기증 가능한 장기 및 절차 죽은 자가 산 자에게 할 수 있는 마지막 선행이자 가장 숭고한 행위.  이식대기자 등록방법: 환자 등록신청(http://konos.go.kr/) → 이식의료기관(코디네이터)→ K-net 프로그램에 입력 *출처: 보건복지부, 대한의약회
  24. 24. 2014-05-04 Volunteer for 5k Race for Hope 2013-12-28 소아암 봉사활동 2014-04-10 EndPoverty 2030 참여 및 지지 Unicef 정기 후원
  25. 25. 5.맺음말
  26. 26. 마음을 가다듬고, 저 광야를 가는 무소의 외뿔처럼 홀로 가라 〈숫타니파타〉 中  큰 변화를 이끌어 낼 수 있는 작은 실천들은 두려움과 편견속에 스스로를 던지는데에 있습니다.  세상을 긍정적으로 변화시키는 일은 때로는 어렵고 두렵게만 다가올 것입니다.  저는 아산서원이 여러분들에게 있어 그러한 편견과 두려움을 깨는 하나의 계기가 되길 바랍니다.
  27. 27. 나눔특강Q&A


+ Recent posts