Updated:

객체의 기초 ① 객체 리터럴

자바스크립트에서는 원시 타입을 제외한 모든 값이 객체이다. 객체는 자바스크립트에서 가장 중요한 데이터 타입이다. 객체는 객체 리터럴과 생성자로 생성할 수 있다.

객체

객체는 이름과 값을 한 쌍으로 묶은 데이터를 여러 개 모은 것이다. 즉, 객체는 데이터 여러 개를 하나로 모은 복합 데이터로 연관 배열 또는 사전이라고도 부른다.
객체에 포함된 데이터 하나(이름과 값의 쌍)를 가리켜 객체의 프로퍼티라고 부르고 프로퍼티의 이름 부분을 프로퍼티 이름 또는 라고 부른다.

객체 리터럴로 객체 생성하기

다음 코드는 트럼프 카드의 정보를 객체 리터럴로 표현한 것이다.

var card = { suit: "하트", rank: "A" };

{…} 부분이 바로 객체 리터럴이며, 객체 리터럴을 변수 card에 대입하고 있다. 프로퍼티 이름과 프로퍼티 값은 suit: “하트”처럼 클론(:)을 사용하여 구분하며 중괄호({})안에 있는 프로터티들은 쉼표(,)로 구분한다. 프로퍼티 이름으로는 모든 식별자와 문자열 리터럴(빈 문자열고 사용 가능)을 사용할 수 있다. 즉 앞 코드에 있는 프로퍼티 이름은 문자열로 바꾸어 작성할 수 있다.

var card = { "suit": "하트", 'rank': "A" };

프로퍼티 값에는 모든 데이터 타입의 값과 표현식을 대입할 수 있다.
변수에 대입된 객체 안의 프로퍼티 값을 읽거나 쓸 때는 마침표(.) 연산자 또는 대괄호([]) 연산자를 사용한다.

card.suit // 하트
card["rank"] // A

마침표로 프로퍼티를 읽거나 쓸 때는 프로퍼티 이름 즉, 식별자만 사용할 수 있다. 대괄호로 프로퍼티를 읽거나 쓸 때는 프로퍼티 이름 또는 문자열을 반환하는 표현식을 사용할 수 있다.
객체에 없는 프로퍼티를 읽으려고 시도하면 undefined를 반환한다.

card.color // undefined

객체 리터럴 안에 어떠한 프로퍼티도 작성하지 않으면 빈 객체가 생성된다.

var obj = {};
console.log(obj); // Object{}

프로퍼티 추가와 삭제

없는 프로퍼티 이름에 값을 대입하면 새로운 프로퍼티가 추가된다.

card.value = 14;
console.log(card); // Object {suit: "하트", rank: "A", value: 14}

delete 연산자를 사용하면 프로퍼티를 삭제할 수 있다.

delete card.rank;
console.log(card); // Object {suit: "하트", value: 14}

in 연산자로 프로퍼티가 있는지 확인하기

in 연산자를 사용하면 객체에 특정 프로퍼티가 있는지 확인할 수 있다. 프로퍼티가 객체에 포함되었을 때는 true를 반환하고 포함되지 않았을 때는 false를 반환한다.

var card = { suit: "하트", rank: "A"};
console.log("suit" in card);  // true
console.log("color" in card); // false

원래 toString 프로퍼티는 card 객체 안에 없지만 다음 코드를 보면 toString 프로퍼티가 card에 있다는 결과가 나온다.

console.log("toString" in card); // true

이는 card가 Object 객체를 상속받았기 때문이다.

객체 리터럴 예제

좌표평면의 점을 표현하는 객체

var p = { x: 1.0, y: 2.5};

원을 표현하는 객체

var circle = {
    center: { x: 1.0, y: 2.0}, // 원의 중점을 표현하는 객체
    radius: 2.5                // 반지름
}

메서드

프로퍼티에 저장된 값의 타입이 함수면 그 프로퍼티를 메서드라고 부른다.

객체는 참조 타입

객체 타입의 값을 변수에 대입하면 그 변수에는 객체의 참조(메모리에서의 위치 정보)가 저장된다. 이때의 변수 상태를 가리켜 그 객체를 참조하고 있다라고 한다.
변수에 저장된 객체의 참조는 다른 원시 값과 마찬가지로 다른 변수에 저장할 수 있다.

var a = card;

그러면 변수 a가 card 객체를 참조하게 되므로 a로 card 객체를 읽거나 수정할 수 있다.

console.log(a.suit);    // 하트
a.suit = "스페이드";
console.log(a.suit);    // 스페이드
console.log(card.suit); // 스페이드


함수의 기초

함수는 자바스크립트 프로그래밍 언어를 규정하는 가장 중요한 구성 요소이다.

함수

자바스크립트에서 함수는 일련의 처리를 하나로 모아 언제든 호출할 수 있도록 만들어 둔 것이다. 입력값을 받으면 출력 값으로 함수 값을 반환한다. 자바스크립트에서 함수의 입력 값을 인수라고 부르고 함수의 출력 값을 반환값이라고 부른다.

함수 선언문으로 함수 정의하기

함수는 function 키워드를 사용해서 정의한다.

function square(x) { return x*x; }

함수 이름

변수 이름과 마찬가지로 모든 식별자를 함수 이름으로 사용할 수 있다. 그러나 함수 이름은 해당 함수의 기능을 이해하기 쉽게 지어야 한다.

함수 호출

함수를 호출하려면 함수 이름 뒤에 소괄호로 인수를 묶어 입력한다.

square(3) // 9

함수를 호출할 때 전달하는 값을 인수(argument), 함수 정의문의 인수를 인자(parameter)라고 한다.

인수

함수는 인수를 여러 개 받을 수 있다. 인수가 여러 개라면 인수와 인수를 쉼표(,)로 구분한다. 예를 들어 다음 함수 dist는 두 점 사이의 거리를 구하는 함수이다.

function dist(p,q){
    var dx = q.x - p.x;
    var dy = q.y - p.y;
    return Math.sqrt(dx*dx+dy*dy);
}

var p1 = {x:1, y:1};
var p2 = {x:4, y:5};
var d = dist(p1,p2); //5

인수를 받지 않는 함수도 정의할 수 있다.

var bark = function() { console.log("Bow-wow"); };
bark(); // "Bow-wow"

bark 함수에는 인수도 없고 return 문도 없다. return 문이 실행되지 않은 상태에서 제어권이 함수를 호출한 코드로 되돌아가면 함수의 반환값이 undefined가 된다.

console.log(bark()); // undefined

함수의 실행 흐름

 • 호출한 코드에 있는 인수가 함수 정의문의 인자에 대입된다.
 • 함수 정의문의 중괄호 안에 작성된 프로그램이 순차적으로 실행된다.
 • return 문이 실행되면 호출한 코드로 돌아간다. return 문의 값은 함수의 반환값이 된다.
 • return 문이 실행되지 않은 상태로 마지막 문장이 실행되면, 호출한 코드로 돌아간 후에 undefined가 함수의 반환값이 된다.

함수 선언문의 끌어올림

자바스크립트 엔진은 변수 선언문과 마찬가지로 함수 선언문을 프로그램의 첫머리로 끌어올린다. 함수 선언문은 프로그램의 어떤 위치에도 작성할 수 있다.

console.log(square(5)); // 25
function square(x) { return x * x; }

값으로서의 함수

자바스크립트에서는 함수가 객체이다. 함수 선언문으로 함수를 선언하면 내부적으로는 그 함수 이름을 변수 이름으로 한 변수와 함수 객체가 만들어지고, 그 변수에 함수 객체의 참조가 저장된다. 이 변수 값을 다른 변수에 할당하면 그 변수 이름으로 함수를 실행할 수 있다.

var sq = square;
console.log(sq(5)); // 25

참조에 의한 호출과 값에 의한 호출

함수는 원시 값을 인수로 넘겼을 때와 객체를 인수로 넘겼을 때 다르게 동작한다. 먼저 인수가 원시 값일 때 어떻게 동작하는지 예제를 살펴본다.

function add1(x) { return x = x + 1; }
var a = 3;
var b = add1(a);
console.log("a = " + a + ", b = " + b); // a = 3, b = 4

add1은 전달받은 인수에 1을 더하여 반환하는 함수이다. 이 함수가 호출될 때 변수 a의 복사본이 인자 x에 할당된다. 즉, 인수에 원시 값을 넘기면 그 값 자체가 인자에 전달된다. 이르 가리켜 값의 전달이라고 부른다. 이때 변수 a와 변수 x는 다른 영역의 메모리에 위치한 별개의 변수이다. 따라서 x 값을 바꾸더라고 a 값은 바뀌지 않는다.
다음으로 인수가 객체일 때 어떻게 동작하는지 예제를 살펴본다.

function add1(p) { p.x = p.x + 1; p.y = p.y + 1; return p; }
var a = {x:3, y:4};
var b = add1(a);
console.log(a, b); // Object {x=4, y=5} Object {x=4, y=5}

이번에 등장한 add1 함수는 2차원 좌표의 각 성분에 1을 더한 좌표를 반환하는 함수이다. 함수가 호출될 때 변수 a의 복사본이 인자 p에 할당된다. 여기까지는 원시 값을 인수로 넘겼을 때와 동일하게 동작하지만 이전과 다르게 변수 a에 객체 {x:3, y:4}의 참조가 저장되어 있으며, 이 참조 값을 인자 p에 대입한다. 즉, 인수로 넘겼을 때 전달되는 값은 참조 값이다. 이를 가리켜 참조 전달이라고부른다.
인수 여러 개를 우아하게 전달하는 방법(elegant way)
함수에 넘겨야 하는 인수 개수가 많아지면 다음과 같은 문제가 발생한다.
 • 인수의 순서를 착각하기 쉽다.
 • 함수가 받는 인수 개수를 바꾸면 함수의 호출 방법이 바뀌므로 프로그램 전체를 수정해야 한다.
객체의 프로퍼티에 인수를 담아서 넘기면 이러한 문제를 우아하게 해결할 수 있다. 다음과 같이 인수가 많은 함수를 예로 들어본다.

function setBallProperties(x, y, vx, vy, radius) { ... }
...
setBallProperties(0, 0, 10, 15, 5);

이 함수의 인수를 다음과 같이 객체의 프로퍼티에 담아서 함수에 넘기도록 고쳐 본다.

var parameters = {
    x: 0,
    y: 0,
    vx: 10,
    vy: 15,
    radius: 5,
    color: "blue"
};
setBallProperties(parameters);

단, 함수 안에서 객체릐 프로퍼티를 수저아면 호출한 코드에 있는 객체의 프로퍼티가 함께 바뀌므로 주의해야 한다. 객체를 인수로 넘기면 함수에는 객체의 참조가 전달되기 때문이다.

변수의 유효 범위

전역 유효 범위와 지역 유효 범위
변수에 접근할 수 있는 범위를 그 변수의 유효 범위(scope)라고 한다. 유효 범위를 결정하는 방법에는 프로그램의 구문만으로 유효 범위를 정하는 어휘적 범위(lexical scope)와 프로그램 실행 중에 범위를 정하는 동적 범위(dynamic scope)이 있다. 자바스크립트의 변수는 전역 변수지역 변수가 있다. 전역 변수는 함수 바깥에서 선언된 변수로 유료 범위가 전체 프로그램이고 지역번수는 함수안에서 선언된 변수와 함수 인자로 유효 범위는 변수가 선언된 함수 내부이다.
변수의 충돌
변수에 유효 범위가 있는 이류는 프로그램의 다른 부분에서 선언된 이름이 같은 변수와 충돌하지 않도록 하기 위해서이다.
함수 안에서의 변수 선언과 변수 끌어올림
함수 안에서 선언된 지역 변수의 유효 범위는 함수 전체이다. 함수 중간 부분에서 변수를 선언하더라도 변수는 함수 첫머리에서 선언된 것처럼 함수 안의 다를 문장보다 먼저 생성된다.
함수 안에서의 변수 선언 생략
변수를 선언하지 안은 상태에서 값을 대입하면 전역 변수로 선언된다.

블록 유효 범위 : let과 const

let과 const는 ECMASript 6부터 추가된 변수 선언자로 모두가 ‘블록 유효 범위’를 갖는 변수를 선언한다. 블록 유효 범위를 가진 변수는 중괄호({}) 안에서만 유효하다. let은 변수를 선언하고 const는 한 번만 할당할 수 있는 상수를 선언한다.
let 선언자
let 문은 블록 유효 범위를 작는 지역 변수를 선언한다. 사용법은 var 문과 같다.

let x;
let a, b, c;
let x = 5, y = 7;

var로 선언한 변수와 let으로 선언한 변수의 가장 큰 차이점은 let으로 선언한 변수의 유효 범위가 블록 안이라는 점이다.
const 선언자
const 문은 블록 유효 범위를 가지면서 한 번만 할당할 수 있는 변수(상수)를 선언한다. const로 선언한 상수는 let 문으로 선언한 변수처럼 동작한다. 단, 반드시 초기화해야 한다는 차이점이 있다.

const c = 2;
// c = 5; const 문으로 선언한 변수에 다시 대입을 시도하면 타입오류가 발생한다.
const origin = {x:1, y:2}; // const 문으로 선언한 상수 값이 객체이거나 배열일 경우에는 프로퍼티 또는 프로퍼티 값을 수정할 수 있다.
origin.x = 3;
console.log(origin) // Object {x:3, y:2}

함수 리터럴로 함수 정의하기

함수는 함수 리터럴로도 정의할 수 있다. 예를 들어 앞에서 예로 들었던 함수 square는 다음과 같이 함수 리터럴로 수정할 수 있다.

var square = function(x) { return x * x; };

이 코드에서는 function(x) {…} 부분이 함수 리터럴이다. 함수 리터럴은 이름이 없는 함수이므로 익명 함수 또는 무명 함수라고 부른다. 함수 선언문에서는 끝에 세미클론을 붙일 필요가 없지만 함수 리터럴을 사용할 때는 끝에 반드시 세미클론을 붙어야 한다. 함수 선언문으로 정의한 함수와 함수 리터럴로 정의한 함수 사용법은 같다. square(5)라고 작성하면 함수를 실행할 수 있다. 한 가지 차이점이라면 자바스크립트 엔진이 함수 선언문으로 정의한 함수는 끌어올리지만 함수 리터럴로 정의한 함수는 끌어올리지 않는다는 점이다.
익명 함수에도 이름을 붙일 수 있다.

var square = function sq(x) { return x * x; };

그러나 코드에서 sq라는 아름은 함수 안에서만 유효하므로 함수 바깥에서는 sq라는 이름으로 함수를 호출할 수 없다.

객체의 메서드

객체의 프로퍼티 중에서 함수 객체의 참조를 값으로 담고 있는 프로퍼티를 가리켜 메서드라고 부른다. 메서드를 정의할 때는 프로퍼티 값으로 함수 리터럴을 대입한다. 예를 들어 원을 그리는 객체에 원의 넓이를 구하는 메서드인 area를 추가할 수 있다.

var circle = {
    center: { x:1.0, y:2.0 }, // 원의 중점을 표현하는 객체
    radius: 2.5,              // 원의 반지름
    area: function () {       // 원의 넓이를 구하는 메서드
        return Math.PI * this.radius * this.radius;
    }
};

함수 객체 안에 적힌 this는 그 함수를 메서드로 가지고 있는 객체를 가리킨다. 메서드는 일반 함수와 마찬가지로 소괄호를 붙여서 실행한다.

circle.area() // 19.634954084936208

매서드 또한 프로퍼티의 일종이므로 나중에 추가할 수 있다. 예를 들어 객체 circle에 원을 평행으로 이동시키는 translate 메서드를 추가할 수 있다.

circle.translate = function(a, b) {
    this.center.x = this.center.x + a;
    this.center.y = this.center.y + b;
};

이 메서드를 실행하면 다음과 같은 결과가 나온다.

circle.translate(1, 2);
circle.center;  // Object { x=2, y=4} 

이 예에서 알 수 있듯이 메서드는 일반적으로 메서드가 속한 객체의 내부 데이터(프로퍼티 값) 상태를 바꾸는 용도로 사용한다. 이러한 객체를 기본 부품으로 삼아 프로그램을 만들어 가는 기법을 가리켜 객체 지향 프로그래밍이라고 부른다.

함수를 활용하면 얻을 수 있는 장점

함수를 활용하면 다양한 효과를 기대할 수 있다.
재사용할 수 있다
같은 코드를 여러 번 작성할 필요가 없어지므로 프로그램이 간결해진다.
만든 프로그램을 이해하기 쉽다
함수를 사용하면 일정한 처리를 모아서 이름을 붙일 수 있다. 이는 함수 안에 상세한 내용을 숨기는 효과가 있다.
프로그램 수정이 간단해진다
함수로 정리해 두면 해당 함수만 수정하면되므로 수정이 간단해진다.

객체의 기초 ② 생성자

이 절에서는 생성자로 객체를 생성하는 방법을 배운다.

생성자로 객체 생성하기

자바스크립트에는 클래스가 없지만 생성자라고 하는 함수로 객체를 생성할 수 있다.
간단한 예
다음 코드는 트럼프 카드를 표현하는 객체를 생성하는 생성자이다.

function Card(suit, rank) {
    this.suit = suit;
    this.rank = rank;
}

생성자로 객체를 생성할 때는 new 연산자를 사용한다.

var card = new Card("하트", "A");

이 코드를 실행하면 suit 프로퍼티에는 “하트”, rank 프로퍼티에는 “A”라는 값이 저장된 객체다 생성되고, 마지막으로 그 객체의 참조가 변수 card에 할당된다.

console.log(card); // Card {suit: "하트", rank: "A"}

이때 Card 생성자로 생성한 객체를 Card 객체라고 부른다. console.log로 객체를 출력하면 앞에 생성자 이름이 표시된다.
생성자
new 연산자로 객체를 생성할 것이라 기대하고 만든 함수를 생성자라고 부른다. 생성자 이름은 관례적으로 그것이 생성자임을 알리기 위해 첫 글자를 대문자로 쓴다. 생성자 안에서 this.프로퍼티 이름에 값을 대입하면 그 이름을 가진 프로퍼티에 값이 할당된 객체가 생성된다. 앞의 예는 다음과 같이 객체 리터럴로 고쳐 쓸 수 있다.

var card = {};
card.suit = "하트";
card.rank = "A";

생성자와 new 연산자로 생성한 객체를 그 생성자의 인스턴스(실체)라고 부른다.
생성자릐 역할
생성자는 객체를 생성하고 초기화하는 역할을 한다. 생성자를 사용하면 이름은 같지만 프로퍼티 값이 다른 객체(인스턴스) 여러 개를 간단히 생성할 수 있다.

var card1 = new Card("하트", "A");
var card2 = new Card("클럽", "K");
var card3 = new Card("스페이드", "2");

이처럼 생성자를 사용하면 이름이 같지만 프로퍼티 값이 다른 객체 여러 개를 효율적으로 생성할 수 있다.
생성자는 함수이므로 프로퍼티에 값을 대입할 수 있다. 다른 함수와 마찬가지로 다양한 처리를 할 수도 있다. 이를 활용하면 객체를 생성할 때 초기화 작업을 병행할 수 있다.

매서드를 가진 객체를 생성하는 생성자

생성자에서 this.프로퍼티 이름에 함수의 참조를 대입하면 메서드를 정의할 수 있다.

function Circle(center, radius) {
    this.center = center;
    this.radius = radius;
    this.area = function() {
      return Math.PI * this.radius * this.radius;
    };
}
var p = {x:0, y:0};
var c = new Circle(p, 2.0);
console.log("넓이 = " + c.area()); // 넓이 = 12.566370614359172

객체의 기초 ③ 내장 객체

자바스크립트에는 처음부터 사용할 수 있는 내장 객체(빝트이 오브젝트)가 마련되어있다. 내장 객체는 자바스크립트라는 프로그래밍 언어의 뻐대를 구성한다.

내장 생성자

자바스크립트에서 사용할 수 있는 생성자에는 사용자가 정의하는 생성자 외에도 자바스크립트에 처음부터 포함된 ‘내장 생성자’가 있다. 내장 생성자에는 이미 유용한 프로퍼티와 메서드가 마련되어 있으므로 내장 생성자를 이용하여 객체를 생성하면 다양한 작업을 쉽게 처리할 수 있다.

Date 생성자

Date 생성자는 날짜와 시간을 표현하는 객체를 생성한다. Date 객체에 내장된 다양한 메서드를 활용하면 날짜와 시간 처리를 간단하게 할 수 있다. Date 객체는 Date 생성자로 생성한다.

var now = new Date(); // 실행한 시점의 날짜와 시간 정보를 담은 객체 생성
console.log(now);     // Date {Tue Aug 01 2017 09:41:54 GMT+0900 (KST)}

Date 생성자의 인수로 날짜와 시간을 전달하면 그 날짜와 시간을 가라키는 Date 객체가 생성되고 Date 객체는 계산식 안에서 밀리초 단위 정수로 값의 타입이 바뀐다.

var then = new Date(2008, 5, 10);
console.log(then); // Date {Tue Jun 10 2008 00:00:00 GMT+0900 (KST)}

var elapsed = now - then;
console.log(elapsed); // 245177916548

이 성질을 활용하면 프로그램 실행에 걸리는 시간을 밀리초 단위로 구할 수 있다.

var start = new Date();
var end = new Date();
var elapsed = end - start; // 프로그램 실행에 걸리는 시간(밀리초 단위)

다음은 Date 객체가 제공하는 주요 메서드이다.

now.getFullYear()         // 2016(연도를 뜻하는 숫자 값)
now.getMonth()            // 4(월을 뜻하는 숫자 값. 0부터 시작하므로 이 경우에는 5월을 뜻함)
now.getDate()             // 17(날짜를 뜻하는 숫자 값)
now.getDay()              // 4(요일을 뜻하는 숫자 값. 일요일이 0이므로 이 경우에는 목요일을 뜻함)
now.getHours()            // 16(시각의 시간을 뜻하는 숫자 값)
now.getMinutes()          // 50(시각의 분을 뜻하는 숫자 값)
now.getSeconds()          // 55(시각의 초를 뜻하는 숫자 값)
now.getMilliseconds()     // 257(시각의 밀리초를 뜻하는 숫자 값)
now.toString()            // "The Mar 17 2016 16:50:55 GMT+0900(KST)"
now.toLocaleString()      // "2016/3/17 16:50:55" (지역화된 시간과 날짜 정보)
now.toLocaleDateString()  // "2016. 3. 17." (지역화된 날짜 정보)
now.toLocaleTimeSting()   // "오후 4:50:55" (지역화된 시간 정보)
now.getUTCHours()         // 7(UTC(협정 세계 시) 시각의 시간을 뜻하는 숫자 값)
now.toUTCString()         // "Sun, 17 Apr 2016 07:50:55 GMT" (UTC 시각과 날짜 정보)

Function 생성자

Function은 함수를 생성하는 내장 생성자이다.

var square = new Function("x", "return x * x");

이때 첫 번째 인자인 “x”는 인수의 이름을 뜻하는 문자열이고 두 번째 인수는 함수 몸통(function body)이 작성된 문자열이다. 일반적으로 인수가 n개일 때는 다음과 같이 사용한다.

var 변수 이름 = new Function( 번째 인수, ... , n번째 인수, 함수 몸통); 

Function 생성자로 생성한 함수는 전역 변수와 자신의 지역 변수만 읽고 쓸 수 있다는 단점이 있어서 함수를 동적으로 생성해야 하는 특별한 상황 외에는 사용하지 않는다. 또한 악의를 품은 사용자가 입력한 문자열을 Function 생성자의 인수인 ‘함수의 몸통’으로 전달하면 악성 코드가 실행되어 보안 문제가 발생할 수도 있다.

기타 내장 객체

자바스크립트에서는 처음부터 사용할 수 있는 객체를 가리켜 내장 객체(빌트인 오브젝트)라고 부르며, 앞서 설명한 내장 생성자가 내장 객체를 생성한다.

내장 객체 설명
전역 객체 프로그램 어디에서나 사용할 수 있는 객체
JSON JSON을 처리하는 기능을 제공
MATH 수학적인 함수와 상수를 제공
Reflect 프로그램으 흐름을 가로채는 기능을 제공

전역 객체

전역 객체의 프로퍼티는 프로그램의 어느 위치에서나 사용할 수 있다.

분류 프로퍼티
전역 프로퍼티 undefined, NaN, Infinity
생성자 Object(),String(), Number() 등
전역 함수 parseInt(), parseFloat(), isNaN() 등
내장 객체 Math, JSON, Reflect

자바스크립트 객체의 분류

자바스크립트 객체는 크게 네이티브 객체, 호스트 객체, 사용자 정의 객체로 나눌 수 있다.
네이티브 객체
ECMAScript 사양에 정의된 객체가 네이티브 객체(native object)이다. 내장 생성자로 생성된 객체와 JSON, Math, Reflect 등이 네이티브 객체이다.
호스트 객체
ECMAScript에는 정의되어 있지 않지만 자바스크립트 실행 환경에 정의된 객체가 호스트 객체(host object)이다. 브라우저 객체, DOM에 정의되어 있는 객체, Ajax를 위한 XMLHttpRequest 객체, HTML5의 각종 API 등이 클라이언트 측 자바스크립트에 정의된 호스트 객체의 예이다.
사용자 정의 객체
사용자가 정의한 자바스크립트 코드를 실행한 결과로 생성된 객체가 사용자 정의 객체이다.

배열의 기초

배열은 값의 목록으로 값마다 번호가 매겨져 있다. 배열을 활용하면 다양한 알고리즘을 표한할 수 있다.

배열 리터럴로 생성하기

배열 리터럴은 쉼표로 구분한 값을 대괄호([])로 묶어서 표현한다.

var evens = [ 2, 4, 6, 8 ];

위 코드에서 […] 부분이 배열 리터럴이며 배열 값 하나를 배열 요소라고 부른다. 배열 요소에는 왼쪽부터 순서대로 0, 1, 2 … 라는 번호가 매겨져 있다. 요소에 매긴 번호는 요소 번호 또는 인덱스라고 부른다.

var empty = [];     // 배열 리터럴 안에 어떠한 요소도 작성하지 않으면 빈 배열이 생선된다.
console.log(empty); // []

var a = [2, , 4];   // 배열 리터럴 요소의 값을 생략하면 그 요소는 생성되지 않는다.
console.log(a);     // [ 2, undefined, 4]

var various = [ 3.14, "pi", true, {x:1, y:2}, [2, 4, 6, 8] ]; // 배열의 요소에는 변수와 마찬가지로 모든 타입의 값이 올 수 있다.

length 프로퍼티

배열의 length 프로퍼티에는 배열 요소의 쵀대 인덱스 값 +1이 담겨 있다.

var evens = [ 2, 4, 6, 8 ];
evens.length // 4

length 프로퍼티 값을 가리켜 배열 길이라고 부른다. 자바스크립트에서는 배열 길이가 배열 요소의 개수를 뜻하지 않는 경우가 있으므로 주의해야 한다.
length 프로퍼티에 현재의 배열 요소 개수보다 작고 0보다 큰 정수 값을 대입하면 배열 길이가 줄어든다.

var a = ["A", "B", "C", "D"];
a.length = 2;
console.log(a); // ["A", "B"]

Array 생성자로 생성하기

배열은 Array 생성자로도 생성할 수 있다.

var evens = new Array(2, 4, 6, 8);  // [ 2, 4, 6, 8 ]을 생성
var empty = new Array();            // 빈 배열 []을 생성
var a = new Array(2, 4);            // 배열 리터럴 [2, 4]와 똑같은 비열을 생성
var various = new Array(3.14, "pi", true, {x:1, y:2}, [2, 4, 6, 8]);

Array 생성자의 인수가 한 개고 그 값이 양의 정수면 의미가 달라진다. 이때 인수는 배열 길이를 뜻하므로 배열이 그 길이만큼 생성된다.

var x = new Array(3);
console.log(x.length); // 3

배열 요소의 참조

특정 인덱스의 요소는 대괄호([]) 연산자를 사용해서 읽거나 쓸 수 있다.

evens[2] // 6

배열은 객체

자바스크립트의 배열은 Array 객체이며 객체로 배열의 기능을 가상으로 흉내 낸 것이다. 배열에 대괄호 연산자를 사용하는 것은 객체에 대괄호 연산자를 사용하는 것과 마찬가지이며, 배열의 요소 번호로 숫자 값 대신 문자열을 사용할 수 있다.

var a = ["A", "B", "C", "D"];
console.log(a["2"]);  // C
a[4]  // undefined, 없는 배열 요소를 읽으려고 시도하면 undefined가 반환된다.

참고로 ECMAScript 6부터는 TypedArray 객체가 추가되어 C나 Java 등의 배열과 마찬가지로 메모리의 연속된 공간에 차례대로 배치된다.

배열 요소의 추가와 삭제

없는 배열 요소에 값을 대입하면 새로운 요소가 추가되고 push 메서드를 사용하면 요소를 배열 끝에 추가할 수 있다. delete 연산자를 사용하면 특정 배열 요소를 삭제할 수 있다.

var a = ["A", "B", "C"];
a[3] = "D";
console.log(a); // ["A", "B", "C", "D"]

var b = ["A", "B", "C"];
b.push("D");
console.log(b); // ["A", "B", "C", "D"]

delete a[1];
console.log(a); // ["A", undefined, "C", "D"]

delete 연산자를 사용하여 배열의 요소를 삭제해도 그 배열의 length 프로퍼티 값은 바뀌지 않고 삭제한 요소만 사라진다.

희소 배열

배열에 요소를 추가하거나 제거하면 인덱스가 0부터 시작되지 않는 배열이 만들어진다. 이러한 배열을 희소 배열이라고 부른다.

var a = ["A", "B", "C"];
a[4] = "E";
console.log(a); // ["A", "B", "C", undefined, "E"]

위 코드를 실행하여 결과를 보면 a[3]이 undefined라고 표시되지만 실제로 저 요소는 없다.

댓글남기기