First Step

Wordbank

Principle of coding(코딩 원리):

  • 한 단계씩 실행(Step by step)

  • 조건 실행(Conditional execution)

  • 반복 실행(Loop)

  • 묶어서 재사용(Function and all kinds of reusability - blocked and packaged codes to call and use repeatedly in everywhere)

    한 단계씩 실행은 컴퓨터를 정확하게 하고, 조건 실행은 컴퓨터를 똑똑하게 하고, 반복 실행은 컴퓨터를 강력하게 하고, 묶어서 재사용은 컴퓨터를 효율적이게 한다. 컴퓨터 프로그래밍의 발전은 이런 핵심 원리를 가지고 코드의 재사용성, 유지보수 효율, 가독성을 높이는 방법을 찾는 방향으로 진행되고 있다.


  1. Console: 본래는 컴퓨터 사용자와 데이터 처리 시스템 사이에 통신을 위해 사용하는 컴퓨터 단말 장치(입출력 조작대)를 일컫는다. 입출력 조작대에는 디스플레이 혹은 타이프라이터가 있어서 컴퓨터와 통신한 내용을 표시하도록 되어 있다.

  2. Console.log( ): console은 전역 객체(global object)다. 콘솔 창에 결과를 보여준다. Console 객체가 -log( ) 메소드를 호출하면 ‘문자열’을 파라미터(매개변수)에 전달하여 그대로 출력한다. 참고로, log는 라틴어로 ‘말’이라는 단어 log(ue)에서 유래하여, 글로 써놓은 기록을 뜻한다.

  3. 데이터 타입(JavaScript Data type): 숫자(number), 문자(string), 불린(Boolean), null, undefined의 원시 데이터 타입(primitive data type)과 배열(array)과 같은 참조 데이터 타입(reference data type) 등 프로그램 언어들이 사용하는 데이터의 종류다.

  4. 배열(Array): 변수는 하나의 데이터를 저장하지만, 배열은 연관된 복수의 데이터를 한 곳에 모아서 관리하는데 사용하는 데이터 타입이다. 배열을 사용하면 하나의 변수에 여러 개의 데이터를 한 번에 저장할 수 있다. 배열 안에 담겨진 각 데이터는 원소(element)라고 한다. 배열은 반복문과 결합하면 효용성이 커진다. 배열을 사용해 다양한 입력값들을 한 번에 넣은 후, 배열의 리스트 안에 담긴 값(정보)을 반복문을 사용하여 하나씩 호출하여 처리할 수 있기 때문이다. 배열을 사용하는 방식은 다음과 같다.

var member = [‘A’, ‘B’, ‘C’]
  1. 변수(variable): 정보(숫자, 문자)를 담는 컨테이너(container)다. 변수는 프로그램이 작동할 때 언제든지 ‘변할 수 있는 영역’일 경우에 사용한다. 변수를 사용하는 핵심 이유는 ‘코드 재활용’이다. 즉, ‘묶어서 재사용’이라는 코딩의 핵심원리에 따른다. 이런 방식(묶어서 재사용)은 코드의 재사용성, 유지보수 효율, 가독성을 높여 준다.

  2. 반복 실행문(Loop): 반복 실행문은 반복적이어서 지루하거나 실수할 가능성이 있는 일을 컴퓨터가 인간보다 ‘탁월하게’ 잘하게 하는 기능이다. 반복문은 조건이 true에서 false가 될 때까지(조건이 만족될 때까지) 같은 일을 반복해서 수행한다. 대표적인 조건 실행문은 for, while이 있다.

For문은 특정 범위(횟수)가 주어진 경우, 그 범위(횟수)만큼 반복할 때 사용한다. For문은 초기화, 반복 조건, 증감식이 ( )안에 한 번에 들어간다. 참고로, For문은 ‘얼만큼(범위) 반복하지?’에 촛점이 맞춰 있다. For문을 사용하는 방식은 다음과 같다.

for (초기화; 반복 조건; 증감식) { 반복할 내용 }

While문i(반복횟수)값과 관련된 다양한 요소들을 넣을 수 있도록 초기화, 반복 조건, 증감식이 각기 다른 줄에 기록된다. 그래서 누군가 i값을 다른 의미로 수정하여 원하지 않는 결과를 도출할 위험도 동시에 존재한다. While문은 (반복 횟수를 잘 모르는 등 정보가 부족할 경우) 특정 조건을 주고, 그 조건이 만족 되어질 때까지 반복할 때 사용한다. While문 자체에는 loop(반복)의 범위가 정해져 있지 않고, 반복 조건이 정해져 있어서 특정 조건이 만족할 경우에만 종료할 때 사용한다. 참고로, While문은 ‘어떻게 루프를 빠져 나가지?’에 촛점이 맞춰져 있다. i는 ‘반복하다’란 뜻을 가진 영어 단어 ‘iterate’의 첫 글자로 반복문을 사용할 때 관용적으로 사용하는 문자다.

while(조건) { 반복할 내용 }
  1. 조건 실행문(Conditional execution): 조건 실행문은 컴퓨터가 계산기보다 똑똑하고 인간보다 빠른 비교 판단력을 갖게 하는 기능이다. 여기에도 주의할 문제가 있다. 조건 실행문이 늘어날수록 다른 사람이 코드를 이해하기 어렵다. 조건문을 완전히 없애는 것은 불가능하지만, 가능한 줄이는 것이 좋다. 사용하더라도 중첩의 수준을 2단계까지로 한정하는 것이 좋다. 어떻게 줄일 수 있을까? 함수를 이용해서 조건문을 함수 내부로 이동시키면, 복잡한 조건이 감춰지고 한꺼번에 다룰 수 있다. 조건 자체를 변경하는 것도 가능하다. 복잡한 조건문은 함수의 연속(Cascading)으로 대체할 수도 있다. 대표적인 조건 실행문은 if, switch이 있다.

If문은 특정 조건일 때 실행되는 구문이다. JavaScript에서는 조건이 truthy한 값(Boolean 문맥에서 참으로 간주되는 값 – if(true), if({ }), if([ ]), if(1), if(-1), if(3.14), if(-3.14), if(변수), if(함수), if(Infinity), if(-Infinity) 등)일 때에만 조건이 성립된다고 해석하고, 조건이 falsy한 값(Boolean 문맥에서 거짓으로 간주되는 값 – if(false), if(null), if(undefined), if(0), if(NaN), if(‘ ’), if (“ “), if(document.all) 등)일 경우에는 조건 성립이 안 된다고 규정하여 실행하지 않는다. 참고로, undefined는 ‘(아직) 값이 정의되지 않음’이고, null은 ‘값이 없음’이다. If문을 사용하는 방식은 다음과 같다.

if (조건) { 실행 코드 } 

여러 조건을 중복하거나 결합해 사용하려면 ‘비교 연산자’(예. ===)와 ‘논리 연산자’(예. &&)를 사용한다. 비교는 자체만으로는 효용이 크지 않고, 조건문과 결합할 때 중요한 역할을 한다. 연산자란 값에 대해 어떤 작업을 컴퓨터에게 지시할 때 사용하는 ‘기호’를 의미한다. 즉 비교 연산자는 어떤 값에 대해 비교 작업을 컴퓨터에게 지시할 때 사용하는 기호다.

비교 연산자는 true, false 중 하나를 결과값으로 낸다. JavaScript는 엄격한 비교와 형변환 비교를 사용한다. 엄격한 비교(ex. ===)는 피연산자들이 동일한 타입과 내용을 갖고 있는 조건에서만 true가 된다. 형변환 비교(ex. ==)는 비교하기 전에 피연산자들이 서로 다른 자료형이면 강제로 같은 자료형으로 바꾼 후 비교한다. 참고로, =는 좌항 값을 우항의 변수에 넣는 대입 연산자, ==는 좌항과 우항을 형변환 비교해서 true, false 중 하나를 결과값으로 내는 동등비교 연산자(ex. 1 == “1” 은 true, 좌우항이 데이터 타입이 다르지만 실질 값은 같기 때문), ===는 좌항과 우항이 ‘정확히’ 같은 지를 엄격하게 비교해서 true, false 중 하나를 결과값으로 내는 일치비교 연산자다(ex. 1 === “1” 은 false, 좌우항이 실질 값은 같지만 데이터 타입이 다르기 때문).

논리 연산자는 여러 조건을 결합시키고, 이에 대한 논리를 구성할 때 사용한다. 논리 연산자는 논리적(Boolean) 값과 함께 사용한다.

If문 만으로 컴퓨터가 ‘아주 복잡한 상황’을 처리하는 것은 비효율적이거나 역부족이다. Else 등과 함께 사용하면 복잡한 조건문을 만들어 더 지능적으로 만들 수 있다. 참고로, 반복문 안에 반복문을 중첩할 수도 있고, 조건문 안에 조건문을 중첩할 수도 있고, 반복문 안에 조건문을 넣을 수도 있고, 조건문 안에 반복문을 얼마든지 넣을 수도 있다. 단, 중첩문의 작동방식은 최하위 반복문이나 조건문이 false가 될 때까지(조건이 만족될 때까지) 수행이 된 후에 다시 상위 반복문이나 조건문으로 이동하고 다시 최하위 반복문이나 조건문으로 내려와 false가 될 때까지(조건이 만족될 때까지) 수행이 된 후에 다시 상위 반복문이나 조건문으로 이동하는 순환적 수행을 한다.

  1. 함수(function): JavaScript는 ‘함수형 언어’라는 별명이 붙을 정도로 함수가 차지 하는 위상이 높다. 함수는 ‘코드 재활용’ 즉, 코딩의 핵심원리 중 하나인 ‘묶어서 재사용’의 대표적 방법이다. 하나의 수리연산(數理演算) 논리를 재사용하는 기술이다. 예를 들어, 0~99까지 출력하는 코드를 1000번 반복하라고 할 때 (같은 코드를 1000번 작성하지 않고) 함수를 사용하면 된다. 만약, 함수의 { } 안에 있는 ‘실행 코드’가 수백 수천 줄이 되거나, 코드의 일부를 수정해야 한다면 어떻게 될까? 함수를 사용하지 않은 경우에는 같은 코드 1000개를 모두 수작업으로 작성하거나 수정해야 한다. 이렇게 함수는 ‘(여러 상황에서) 반복해서 호출(사용)’하기 위해 사용한다. 함수를 사용하면 큰 프로그램을 여러 부분으로 분리할 수 있어서 구조적 프로그래밍이 가능하다. 같은 코드를 계속 쓰지 않아서 편리하고 프로그램 용량을 줄일 수 있다. 참고로, 반복문은 그 자리에서 일정한 반복을 기계적으로 수행할 때 사용하는 반면, 함수는 반복적으로 수행해야 할 논리가 프로그램 도처에서 여러가지 맥락으로 반복 호출하여 재수행할 때 효용성이 크다.

코딩에서 함수는 수학의 함수와 개념이 같다. 수학에서 함수(Function, 函數 상자 함, 셈 수)는 변수x와 y사이에서 x값에 따라 y값이 정해지는 대응관계일 때, y는 x의 함수(대응관계)라고 한다. y=ƒ(x) 함수는 두 집합 사이의 ‘대응관계’다. 이를 표현하는 식이 함수 식(대응관계 식)이다. 함수를 사용하는 방식은 다음과 같다.

function 함수이름(매개변수) { 실행 코드 }

함수는 입력(argument), 연산, 출력(return)으로 이루어진다. 입력값을 인자(argument)라 하고, 입력값을 받는 변수ƒ(x)를 매개변수(parameter)라 부른다.

함수의 작동방식은 어떤 루틴(명령어 세트)에서 함수를 호출하면, 함수가 가지는 특정 변수ƒ(x)값을 전달하고 계산을 수행하여 반환값(return value)을 생성한다.

함수를 호출할 때는 ‘함수이름 ( )’를 사용한다. 함수이름 뒤에 ( )가 없으면 컴퓨터는 이것을 함수로 인식하지 않고 변수로 인식한다. ex. number( ); 와 number 차이

함수는 이름, 반환 값(Return Value), 인자(Argument)를 정한 후에, 무슨 기능을 수행할지 명확히 해야한다. 기능은 가능한 구체적이고, 인자는 적을 수록 좋다. 인자가 많으면 함수가 여러가지 일을 할 가능성이 높아진다. 함수도 가능하면 짧게 만들고, 의미 있는 단위의 일 한 가지를 정하는 것이 좋다. 프로그램의 내부 상태 변경도 하고 상태를 읽어오는 등 ‘이 일 저 일 다 하는 함수’는 만들지 말아야 한다. 함수 내부도 복잡하지 않도록, 조건 분기문이나 중첩된 조건문 등은 피해야 한다. 짧은 함수를 만드는 것은 한번에 힘들다. 수시로 더 작은 함수를 만드는 일을 반복하여 다듬어야 한다. 예를 들어, 함수 내부에서 전역 변수를 사용하면 의존 가능성이 발생한다. 이런 일이 어쩔 수 없이 발생할 수 있지만, 함수를 쪼개서 더 작은 함수들로 만드는 방법으로 피해야 한다. 코딩 전에 함수가 할 일을 순서대로 정해 놓으면(주석) 도움이 된다.

JavaScript는 내장 함수와 사용자 정의 함수를 사용한다. 사용자 정의 함수는 프로그래머(사용자)가 직접 만들어 사용하는 함수이고, 내장 함수는 프로그래머(사용자)가 직접 만들지 않아도 JavaScript 안에 이미 내장되어 있는 함수다. ex. alert( ) 이 내장 함수는 확인단추가 있는 메시지 대화상사를 호출한다. prompt( ) 이 내장 함수는 사용자에게 숫자나 문자를 입력받을 수 있는 입력대화상자를 호출한다.

JavaScript모듈 내에 있는 사용자 정의 함수도 크게 두 종류다. 외부에 보여줄 함수(외부 함수)와 내부에서만 사용할 함수(내부 함수)다. 외부에 보여줄 함수는 하나의 헤더 파일에 묶어서 관리한다. 내부에서만 사용하는 함수는 다시 둘로 나뉜다. 그 모듈에서만 사용할 함수, 다른 모듈에서도 사용할 함수다. 후자는 모듈 내에 별도의 계층을 만들어 다른 모듈과 인터페이스를 유지하도록 한다. 단, 다른 외부 모듈과 개별로 직접 접근시키는 것은 좋지 않다. 외부에 의존적인 함수는 모아서 관리하는 것이 더 좋다. 그렇지 않으면, 모듈 역할과 책임이 얽히고, 모듈 간 의존이 높아지고, 응집이 떨어진다. 설계가 힘들고 복잡하다고 아무 생각없이 코딩부터 시작하면 이런 문제가 발생한다. 올바른 문제 정의와 설계(문제해결 역할과 책임을 나누는 일) 과정은 코드 구현, 테스트, 업데이트를 하며 반복적으로 정제(Refinement)된다. 한번에 끝나는 것이 아니다. 때로는 얼마나 해야 끝날지 가늠하기 힘들다. 그래서 설계는 힘들고 복잡하다. 처음부터 완전한 설계를 만들 수 없다. 하지만, 불완전한 설계라도 더 빠르게 가는데 도움이 된다. 바뀌는 계획이라도 없는 것보다 낫다. 끊임없이 변하지만, 지금 어디에 있고, 앞으로 어디로 갈 지를 알려주는 역할은 충분히 하기 때문이다.

함수를 사용할 때, 함수의 기능과 내부 구현을 분리하여 캡슐화(encapsulation)도 가능하다. 캡슐화는 서로 약속된 부분을 제외한 나머지를 ‘변경할 수 없도록’ 감싸서 숨기는 것(정보 은닉, Data hiding)이다.

  1. 객체(Object): JavaScript에서는 현실 세계를 사람이 생각하는 방식(세상이 돌아가는 방식)으로 표현하기 위해 같은 목적이나 기능을 갖는 변수와 함수를 하나로 묶어 객체를 만들고 다양한 객체들끼리 상호 통신하며 프로그램 전체가 작동된다. 모든 사물이 존재하는 이유, 목적, 쓰임새와 하는 일이 정해져 있듯이, 객체도 자신이 해야 할 역할과 책임을 가진 그 자체로 완전한 독립 존재여서 ‘코드 재활용성’을 높일 수 있고, 반복문과 결합하여 사용하면 효용성이 더 높아진다.

JavaScript에서는 함수도 일종의 값(value)으로 취급하기에 변수에 담아 객체를 만들 수 있다. 이럴 경우, 선언된 변수가 하나의 독립된 객체가 된다. 즉, 객체라는 큰 빈상자 안에는 다양한 변수들을 담을 수 있고, 각 변수는 값을 갖는다. 변수가 갖는 값은 일반 데이터나 함수가 된다. 데이터는 물리적 수치, 성별 등이 될 수 있다. 참고로, 객체 안에서 자신의 고유한 값(value)을 가진 변수를 ‘속성(Property)’이라 부른다. 만약, 객체 안에 담겨진 변수(속성)가 함수를 값으로 취하면 그 함수를 메소드(method)라 부른다. 함수가 단독으로 선언될 경우에는 함수라고 불리지만, 객체 안에 key(변수)의 값(value)으로 들어갈 경우는 메소드라 불린다. 대부분 프로그램 언어는 ‘숫자’를 1급시민으로 취급하지만, 자바스크립트는 first-class function(함수를 1급시민으로 취급)을 지원하기 때문이다. 함수를 일급시민으로 취급하면, (대부분 프로그램 언어에서 1급시민으로 취급하는 ‘숫자’처럼) 함수를 변수(variable)에 담을 수 있고, 인자(parameter)로 전달할 수 있고, 반환값(return value)으로 전달할 수 있다. 함수가 값(value)으로 사용될 수 있기 때문에, 당연히 배열의 값으로도 사용될 수 있다. 참고로, 객체는 value에 함수를 넣지 않고 데이터 묶음만 담을 수도 있다. 데이터를 담고 있는 방식으로 볼 때, 객체는 배열처럼 한 바구니에 다양한 데이터를 담을 수 있다. 하지만, 차이점은 배열이 인덱스로 숫자를 사용한다면 객체는 인덱스로 문자를 사용할 수 있다. 배열은 저장된 데이터들이 순서를 가지고 있지만, 객체에 저장된 데이터들은 순서가 없고 key와 value만 있다. key는 객체 안에서 변수(그릇)의 역할을 하고, key 값(value)으로 데이터나 함수를 가질 수 있다. 메소드는 객체 안에서 데이터를 조작하여 ‘동작(behavior, do)’을 결정한다. 동작은 연산(함수)을 말한다. 함수가 내장 함수와 사용자 지정 함수로 나뉘듯, 메소드도 내장 메소드와 사용자 지정 메소드로 나뉠 수 있다. 객체는 상태와 동작으로 구성되는데 ‘상태(state, be)’는 데이터에 의해 결정되고 동작은 함수가 맡는다.

객체는 자신이 해야 할 역할과 책임을 가진 그 자체로 완전한 존재이기에 역할과 책임의 범위를 정해주는 것은 중요한 일이다. 객체가 너무 작으면 역할을 책임지지 못하고, 너무 크면 책임 범위(코드의 크기)가 넓어진다. 둘 다 피해야 한다. 객체의 역할이 모호하면 어떤 일을 의뢰해야 하는지 알 수 없다. 소프트웨어 설계의 대부분은 객체를 포함해서 모듈, 클래스, 시스템의 역할과 책임을 명확하게 하는 일이다.

객체들 간에는 여러 관계를 맺을 수 있다. 대표적으로 ‘상속(Is-A)’, ‘소유(Has-A)’, ‘구성(Part-of)’이 있다. 상속은 서로 동일한 클래스(분류)에서 파생되어, 공통 특성과 공통 메소드(Method)를 가지고 있다. 소유는 다른 객체를 가진다(소유). 구성은 하나의 객체가 여러 다른 객체들로 이루어져 있는 것이다. 이런 관계들을 통해서 객체는 자신의 역할과 책임을 구분하고, 연관된 객체끼리 ‘요청’과 ‘서비스’를 담당하는 방식으로 일을 처리한다.

객체는 자신의 역할과 책임 범위를 ‘계약(인터페이스)’ 형태로 외부에 알려주고, 외부는 그 계약에 기초해서 일을 의뢰한다. 그것을 처리하는 방식과 내부 구조는 해당 객체의 몫이다. 일을 시키는 입장에서는 중요하지 않다. 계약이 이행되는 지만 중요하다. 내부 구조나 속성이 바뀌더라도 계약만 유지되면 된다. 객체도 자신이 맡은 역할만 충실히 하면 된다. 자기 범위를 넘어서면, 더 잘할 수 있는 객체를 찾아서 전달해 주면 된다. 물론, 이런 일(전달)이 일어난다는 것 자체는 자신에게 일을 의뢰한 측에서는 몰라야 한다. 즉, 의뢰인 측에서 그 일을 전달받아 처리하고 있는 객체에 직접 접근할 방법이 없어야 한다. 이런 행위가 귀찮아서 한 객체에게 너무 많은 일을 시키게 되면, 하나의 계약이 영향을 줄 수 있는 범위가 커지게 된다. 결과적으로 계약 자체가 너무 일반화되어 재활용되는 객체 수가 줄어든다. 객체 지향으로 만든 목적 자체가 무너진다. 객체지향 코딩은 객체의 내부 구현은 최대한 감추고(캡슐화), 내부 구현에 의존하지 않고 사용할 수 있는 인터페이스(계약)에 따라 코딩한다. 객체들의 명확히 규정된 역할과 책임 범위를 중심으로 객체와 모듈을 연결하여 프로그램을 작동시킨다. JavaScript처럼 객체지향 코딩은 사물(객체)의 내재된 특징(상태, 역할, 책임)을 구현하는 방법이어서 언어 의존적이 아니다. 코드를 구현하는 사람의 생각에 좌우된다.

참고로, 객체 지향의 3대 특성은 캡슐화, 상속, 다형성이다.

(1) 캡슐화(encapsulation): 캡슐화는 객체지향의 기본 기능이다. 어떤 데이터는 다른 사람이 알거나 변경하지 못하도록 보호해야 한다. 이것이 캡슐화다. 클래스를 사용하여 서로 관련된 정보와 처리 방식을 같이 묶어 버리고, 외부에는 감춘다. 클래스(Class:類)는 객체들을 하나로 묶는 추상이다. 철수와 영희는 ‘사람’이라는 클래스로 묶인다. 각 클래스에는 그 메시지를 처리하는 방식이 있다. 클래스를 사용하면, 객체를 추가하거나 삭제하기 쉬워 요구 사항 변경이 많아도 유연하고 확장성이 높다. 개발된 코드를 재사용할 수 있어 개발 시간과 비용도 줄일 수 있다. 객체(Ouject) 철수는 ‘남자’라는 데이터 속성(Property)을 가진다. 인스턴스(instance)는 같은 클래스에서 생성된 개별 객체다. 추상적 클래스가 구체화되어, 클래스에서 정의된 속성과 성질을 가진 실제 객체로 나타난 것이다. 이렇게 추상 개념인 클래스에서 실제 객체를 생성하는 것을 인스턴스화(instantiation)라 한다. (클래스로부터 객체를 만드는 과정을 인스턴트화라 하고, 어떤 클래스로부터 만들어진 객체를 그 클래스의 인스턴트라고 한다) instance 사전 의미는 ‘사례, 경우’다. 객체끼리는 메시지 송신(送信)으로 상호 통신한다. 어떤 인스턴스에 메시지가 도래하면 그 상위 클래스가 그것을 처리한다.

객체가 데이터와 데이터를 조작할 수 있는 메서드를 같이 묶는 것도 일종의 캡슐화다. 객체는 캡슐화를 통해 데이터는 감추고 외부 세계와 상호작용은 메소드(Method)를 통한다. 메서드만 사용하여 데이터 값을 변경할 수 있게 하려는 이유다. 캡슐화(데이터+메서드)로 객체 독립성이 구조적으로 보장되고 메서드가 데이터 처리를 대신하면, 사용자도 내부를 알 필요 없어 부담이 준다. 내부 구조가 변경되어도 사용자가 알 필요가 없다. 사용자가 데이터를 잘못 건드릴 위험도 없어진다. 사용자는 객체의 메소드 역할과 사용법(메소드가 어떤 기능을 하고, 어떻게 사용하는 지)만 알고, 객체에서 제공하는 인터페이스에 메시지를 보내 메소드를 실행시켜 통신(communication)을 수행하면 된다. 캡슐화를 하면 에러 발생을 최소화되고 코드 재활용도 높아져서 프로그램 관리가 편리해진다.

(2) 상속(inheritance): 상속은 이미 작성된 클래스를 이어 받아서(상속) 새로운 클래스를 생성하는 기법이다. 기존 코드 재활용이다. 객체지향 언어에서 프로그램을 쉽게 확장할 수 있도록 해주는 강력한 수단이다.

(3) 다형성(polymorphism): 다형성은 하나의 이름(방법)으로 많은 상황에 대처하는 기법이다. 개념적으로 동일한 작업을 하는 함수들에 똑같은 이름을 부여하여 코드를 간단하게 만든다.

  1. 전역 객체(global object): 전역 객체는 함수 안과 밖에서 모두 사용할 수 있도록 범위 제한이 없다. 그래서 코드의 어느 부분에서나 사용가능하다. 참고로, 함수 안에서 선언된 변수는 그 함수 안에서만 사용가능하다.

  2. 메소드(method): 본래, 메소드는 ‘기법, 방법’이라는 뜻이다. 객체지향 프로그래밍 언어에서는 객체에 소속되어 있는 ‘서브루틴’으로서 데이터와 변수에 대한 접근권한을 가진 ‘객체의 동작(작업)’을 정의한다. 예를 들어, 엘리베이터라는 객체는 올라감과 내려감이라는 메소드(동작)을 갖는다. 프로그램이 작동하면(런타임), 메소드는 주어진 클래스 인스턴트 내에 저장된 데이터에 접근하고, 값을 변경하는 등의 다양한 동작(작업)을 실시한다. 자주 수행해야 하는 동작(작업)을 메소드로 정의하여 사용하면 코드 양을 크게 줄일 수 있고, 메소드 별로 기능이 분리되어 있어서 필요한 코드를 빨리 찾을 수 있고, 메소드만 수정하면 이를 사용하는 모든 곳에서 즉각 개선이 이루어져 관리 및 유지보수가 편리하다.

  3. 생성자(constructor): 객체를 만드는 역할을 하는 함수다. 생성자 함수 기능은 개별 객체들을 만들 때, 같은 메소드를 중복하여 코딩하는 문제를 해결할 때 강력하다. JavaScript에서 생성자(constructor) 기능은 프로토타입(prototype) 개념과 함께 사용하여 상속(inheritance)을 구현한다. 예를 들어 상속을 받을 개별 객체(인스턴트) ‘밖에서’ 중복해서 사용할 메소드(상속받으면 되는 메소드)를 미리 정의해 prototype chain(객체 원형들을 연결한 고리)으로 묶어놓고, 함수 앞에 new를 붙여 만든 생성자 함수로 새로운 개별 객체를 생성할 때마다 prototype chain 안에 있는 상위(부모), 혹은 상위의 상위(부모의 부모) 등에 있는 각기 다른 상속 요소(메소드)를 골라서 ‘호출해’ 상속하는 방식이다. 마치, 자식의 유전자 생성이 대대로 내려오는 가문의 유전자 띠(chain) 안에서 어떤 부분은 부모에게서, 어떤 부분은 조부모에게서 각기 다르게 상속되는 방식과 같은 효과다. 참고로, Prototype(객체의 원형) 개념은 JavaScript가 상속 기능을 구현할 때 일반적인 객체지향 언어와 구별되는 특징이다.

  4. 모듈(Module): 코드의 기본은 모듈 생성이다. 모듈은 독립 가능한 단위의 생각 덩어리다. 모듈은 "같은 목적을 수행하는 함수들의 집합"이다. 모듈을 사용하는 것도 ‘묶어서 재사용’이라는 코딩의 핵심원리 때문이다. 모듈과 다른 묶어서 재사용 기술들(변수, 함수, 객체 등)과 비교하지만, 모듈은 한 프로그램 안을 넘어 다른 프로그램이나 (웹의 경우) 다른 페이지들에서도 자주 사용할 경우에 유용한 방법이다.

모듈은 큰 프로그램을 여러 개의 집합(파일)로 분리하는 것이다. 이 중 몇 개의 모듈을 합하면 작은 프로젝트가 된다. 모듈은 다른 모듈에 의존적일 수 있고, 모듈 내부를 구성하는 하위 모듈도 존재할 수 있다. 모듈은 자체로 분리되어 컴파일 될 수 있고, 다른 프로그램에도 재사용될 수 있고, 모듈을 개선하면 이것을 사용하는 모든 애플리케이션의 동작도 일시에 개선되기에 전체 프로그램의 효율성을 높인다. 단, JavaScript에는 모듈이라는 개념이 분명하지 않고, 모듈 기능도 제공하지 않는다. JavaScript가 구동되는 호스트 환경에 따라 각기 다르게 제공되는 모듈화 방법을 참고해야 한다.

모듈 생성도 간결이 원칙이다. 객체의 역할과 책임을 분명히 하듯, 각 모듈마다 역할과 책임과 이름을 명확하고 구체적으로 정해야 한다. 모듈 간, 상위와 하위 모듈 간의 관계도 구조를 잘 만들어 복잡도를 최대한 낮추어야 한다. 상하위 모듈의 기본 계층은 3단으로 구성하는 것이 좋다. 상위 계층은 상위 모듈에 대한 인터페이스 제공과 하위 모듈에 대한 운영, 중간 계층은 모듈이 실제 해야할 일 처리, 하위 계층은 의존하는 모듈에 대한 인터페이스를 담당한다. 계층 구조가 가지는 단점인 계층을 무시한 접근은 버스(Bus)나 시스템 호출 등으로 해결하면 된다.

  1. 라이브러리(Library): 라이브러리는 미리 만든 함수들을 모아놓은 곳이다. 모듈이 프로그램을 구성하는 ‘작은 부품’이란 부분에 촛점을 둔다면, 라이브러리는 특정 목적을 구현하는데 자주 사용되는 논리(logic)를 다른 사용자들이 재사용하기 편리하도록 정리한 일련의 코드들의 집합이다. 훌륭한 프로그래머가 되려면 좋을 라이브러리를 선택하여 사용하는 것이 필수다. 대표적인 라이브러리 중 하나를 든다면, jQuery이다. 단, 라이브러리도 유행을 타기 때문에 시간이 지나면서 프로그래머들이 자주 사용하는 라이브러리가 달라진다.

  2. 정규표현식(Regualar Expression): 자신이 찾고자 하는 정보(패턴)를 추출(exec)하고, 자신이 찾고자 하는 정보가 있는지 시험(test)하고, 자신이 찾은 정보를 다른 정보로 치환(replace)하는데 주로 사용한다.

  3. 유효범위(Scope): 변수의 수명을 가리킨다. 예를 들어, 함수 밖에서 변수를 선언하면 전역변수(global variable)가 되어서 애플리케이션 전 영역에서 접근이 가능한 변수가 된다. 반대로, 함수 안에서 변수를 선언하면 지역변수(local variable)이 되어 함수 안에서만 접근이 가능하다. 함수 밖에서 지역변수를 호출하면 실행이 되지 않는다. 대신, 함수 안에서는 지역변수와 전역변수를 함께 호출하면 지역변수가 앞서 실행된다. JavaScript에서는 함수의 중괄호 안에서만 선언된 변수가 지역변수(local variable)가 되고, for문이나 if문의 중괄호 안에서 선언된 변수는 지역변수가 되지 않는다. JavaScript는 함수가 사용될 때가 아니라 함수가 선언(정의)된 시점에서 유효범위가 발생하는 정적 유효범위(static scoping) 혹은 어휘적 유효범위(lexical scoping) 유형이다.