티스토리 뷰

Java Script & HTML

#05. JavaScript의 객체

LichKing 2015. 8. 30. 14:30

자바스크립트는 객체 지향적 코딩을 지원하고있으며 그에 따라 당연히 객체를 생성하고 사용할 수 있다.

자바에서는 객체 생성을 new 연산자로만 지원하는데 반해 자바스크립트는 다양한 방법을 지원하고있으며 그중 2가지 방법을 알아보겠다.


1. 리터럴 표현

리터럴 생성방식에 알아보기전에 리터럴이라는 단어에 대해 잠깐 말해보고자 한다.

'리터럴' 이라는 단어는 거의 대부분의 언어 기초책에서 앞부분에 나오는 단어이다.

그만큼 기초적인 용어인셈인데 이 리터럴이라는 단어에 대해 잘 모르는 개발자가 생각보다 매우 많다.

리터럴이라는 단어는 객체의 생성이나 따로 타입에 대한 추적없이 그 값 자체로 타입을 판별할 수 있는 표현법이다.

말이 좀 어려운데 내가 좋아하는 숫자인 5를 봐보자. 이건 누가 typeof 연산자를 사용해서 타입을 추적하지않아도 당연히 number 타입이란것을 알것이다. "LichKing"을 보자. 지나가던 개발자한테 이게 무슨타입이에요? 라고물어보면 욕한바가지를 먹고 string이라고 대답할것이다. true는 무슨타입인가? boolean타입이다. true값을 적어놓고 이것의 타입을 판별하기위해 typeof true 라는 코드를 작성하진않는다.

리터럴이란 이런것이다. 값 자체로 타입을 나타는 표현법이다.

5, "", true 는 각각 number, string, boolean 타입의 리터럴 표현인것이다.

대부분의 언어 기초책은 변수에 대한 부분을 상당히 앞쪽에 다루고있으며 그것에 대한 설명과 함께 리터럴에 대한 설명이 첨부되어있다. 하지만 변수부분은 대부분 가볍게 보거나 그나마 보지않고 넘어가기때문에 리터럴이란 용어에 생소함을 느끼는 사람들도 많은것이다.

용어에 대한 설명은 여기까지하고,  그럼 객체도 굳이 어려운 코드를 짜지않아도 한방에 객체라는걸 알수있는 문법을 지원하고있다는것을 눈치챈사람도 있을 것이다.

그것이 바로 {}다.

자바와 같은 언어에서 {} 객체보다는 배열에 대한 표현을 지원한다.


String[] arr = {"a", "b"};


이런식일 것이다. 하지만 자바스크립트에서는 객체를 표현하는 법으로 사용되고 있으며 여담으로 배열에 대해 잠깐 말하자면 배열은 [] 표현으로 지원하고있다.

이또한 배열 리터럴 표현이라고 말한다.


var arr = [1, 2, 3];


리터럴 표현은 {}를 지원하고 있으며 자바에서의 객체와 같이 변수와 함수를 담을 수 있다.

변수와 함수를 담을때는 : 표현을 사용하며 각각 멤버에 대한 구분은 , 로 나누고 있다.

표현하자면 이런식이다.


var obj = {

name : "LichKing",

getName : function(){

return this.name;

}

}


사실 자바스크립트에 대해 심화된 공부를 하지않고 그냥 구글링 등을 통해서 자바스크립트나 제이쿼리를 이용해본 사람이라는 알게모르게 이 표현을 꽤나 썼을것이다. 그냥 '아 이건 이렇게 쓰나보다' 하고 별생각없이 갖다 썼던것이 사실은 자바스크립트에서 객체를 표현할때 사용하는 표현식이었던 것이다.


2. 생성자 함수

함수에 대해 설명할때 함수의 3가지 역할 중 하나는 생성자로서의 역할이라고 했다.

생성자를 이용하는 법은 자바에서의 그것과 거의 유사하다. 다만 자바스크립트에서는 클래스가 없기때문에 클래스 없이 생성자만 정의하고 new 연산자를 사용해 객체를 생성한다.


function Const(_name){

this.name = _name;

this.getName = function(){

return this.name;

}

}


var obj = new Const("LichKing");


*언어차원에서 강제적인것은 아니지만 생성자 함수는 대문자로 시작하는것을 권장하고있다.

리터럴 표현때는 인자를 받을 수 없기에 처음 생성할때 값들을 모두 직접 넣어서 생성했다면 생성자 함수를 이용할땐 인자를 이용할 수 있다.

즉 리터럴 방식으로 생성한 객체는 해당 어플리케이션 내에서 1개의 객체만을 생성한다는것이고, 이를 근거로 판단했을때 리터럴 표현은 사실상 싱글톤패턴을 지원한다고 볼수도 있다.


3.Object()

자바스크립트에서 기본적으로 내장되어 제공하는 생성자 함수가 몇 있는데 그중 하나가 Object 함수다.

Object 함수를 활용해서 객체를 생성하게됐을경우에는 멤버가 전혀 없는 빈 객체로 생성되며 사실상 리터럴 표현법과 같은 객체가 생성된다고 보면 된다.


var obj = new Object();


4. 사용법

객체를 생성하는 법은 알아봤고 사용법 역시 자바의 문법과 거의 똑같기 때문에 큰 문제 없이 사용하면 된다.

가령 위 표현법에서 리터럴로 생성한 객체나 생성자 함수를 이용한 객체나 name 멤버를 불러오기위해선


console.log(obj.name);

console.log(obj.getName());


이런식으로 도트(.) 연산자를 이용할 수 있다.

그리고 한가지 표현법을 더 지원하고있는데 위에서 짧게 말했던 배열리터럴을 이용한 표현법도 지원하고있다. 사용하자면 이런식이다.


console.log(obj["name"]);

console.log(obj["getName"]());


조금 더 심화스럽게 생각해보면 자바스크립트에서 객체란 { key : value } 의 map 형태를 띄고있다는걸 볼 수 있다.

우리가 map을 쓸때를 생각해보면 어떻게보면 도트(.) 연산자 보다는 배열표현법이 좀 더 익숙하게 느껴질수도있다.

이런식의 key value 표현 때문에 key가 중복되는 경우는 당연히 가장 마지막에 정의한 멤버가 앞선 멤버들을 모두 덮어쓰게된다.

*객체를 대놓고 map으로 취급해 적극적으로 활용하는 라이브러리가 jQuery다. ajax(), attr() 함수등 거의 대부분의 jQuery 지원함수들이 인자로 객체를 받는다. 이런 경우 동일 함수를 여러번 호출해야되는 경우를 객체로 여러개의 인자를 보내버림으로서 한번의 호출도 모든것을 끝내는것도 가능하다.


var obj = {

name : "lichking",

name : "Lichking",

name : "LichKing"

};


console.log(obj.name);


자바스크립트는 매우 자유로운 문법을 지원하고있기때문에 이미 이번 포스팅에서 배운것을 토대로 충분히 예측할수있지만 예측하기 쉽지않은 이런 표현도 가능하다


function getValue(key){

return {

key1 : "hello",

key2 : "world",

key3 : "javascript"

}[key];

}


getValue("key3");


이런 소스를 짜라고하면 가장 먼저 떠올리는게 switch case 문일텐데 switch case 문을 사용해도 되고 이런식의 표현도 사용이 가능하다.

틀에 박혀 객체를 정의하고 객체.멤버 로만 사용하려하지말고 이런식의 자유로운 패턴을 많이 사용해보자. 이 외에도 보면 바로 문법은 이해되지만 결코 코딩할때 생각치 못했던 표현들이 자바스크립트에선 의외로 많이 있다. 뇌를 말랑말랑하게 만들어보자.


그리고 이런 자바스크립트의 객체리터럴을 토대로 나온 데이터 전송기법이바로 JSON이다.

우리가 매우 친숙하게 제이슨이라고 부르는 이 표현법이 Java Script Object Notation 의 줄임말로 자바스크립트의 객체를 본따 만든것이다. 오리지널 자바스크립트 객체와 다른점은 key가 문자열로 이루어져있다는 것이다.


{

"key1" : "hello",

"key2" : "world",

"key3" : "javascript"

}


이야기가 잠깐 옆으로 샜는데 다시 본론으로 돌아와 자바스크립트의 객체에 대해 얘기를 해보자면 자바의 객체에서는 감히 상상도 못하는 일이 일어나게된다.

그것은 바로 멤버추가가 동적으로 이루어진다는 것이다.

자바에서는 클래스 내에 이 객체가 가질 속성과 메서드들을 정의한 후 new 연산자를 통해 객체를 생성하게되면 그 객체에 변수를 하나 더 추가한다거나 메서드를 하나 더 추가하는 행위는 불가능하다. 그러기위해선 클래스파일에서부터 추가를 한다음 객체를 생성해야한다. 하지만 자바스크립트는 객체를 생성한 이후 동적으로 멤버 추가가 가능하다. 기존 자바개발자들의 발상을 뒤집는 개념이지만 사용법은 어렵지않다.


var obj = new Object();


obj.name = "LichKing";

obj["getName"] = function(){

return this.name;

}


이런식으로 동적으로 추가가 됐기때문에 사실 자바스크립트의 생성자를 자바의 클래스처럼 객체 설계도라고 철썩 같이 믿으면 큰일난다.

분명 생성자에서는 없던 속성이 쭉 아래 내려가보니 호출되고있는 상황이 발생할 수 있는것이다. 아마 중간 어디에서 속성을 추가해줬겠지?

만약 존재하지않는 속성을 호출하게 되더라도 에러가 나는것이 아니라 undefined를 반환하게 된다.

그렇기에 이런 코드가 가능하다


var obj = {};

if(!obj.name){

obj.name = "LichKing";

}


리터럴로 선언한 빈 객체인 obj의 name속성이 있는지 없는지 확인한후 해당 속성이 없으면 추가하는 소스다.


5. 마무리

원래 포스팅할때 이런식으로 숫자를 붙이진 않았는데 표현식을 설명하고자 1, 2를 붙이다보니 3, 4, 5도 붙이게됐다.

객체가 중요하지 않은 언어는 없지만 자바스크립트에서도 객체는 매우 중요하다.

하지만 실무를 뛰다보면 객체에 대한 리터럴 표현법을 몰라 이게 뭔지도 모르면서 '구글치니까 이렇게 보내래' 하고 그냥 무작정 그런식으로 사용하거나 'jQuery에서 지원하는건가보지' 라고 받아들이고 사용하는경우. 하물며는 객체 리터럴을 '배열'이라고 표현하는 사람도 봤다.

어쨋든 에러없이 코딩 잘하면되지 뭐가 문제인가? 라고 생각하는 사람은 굳이 이 포스팅을 볼필요는 없다. 하지만 저런식으로 코딩을 하는사람들은 새로운게 나올때마다 표현법을 배운다고 생각하기 마련이다. 이런 라이브러리를 사용하든 저런 라이브러리를 사용하든 인자를 보낼때 객체를 이용해서 보낸다는것을 알고있는사람은 '아 얘도 객체로 보내는구나 똑같네' 라고 생각하지만 그게 아닌사람들은 지금 보고있는 이 표현이 지난번에 사용했던것이란걸 망각하고 '얘 특이하네' 라고 생각하며 그걸 또 외우고있게된다.

JSON도 객체에 대해 이해한 사람은 '아 키만 문자열로 하면 되는구나' 하고 사용하지만 JSON을 완전히 새로운 걸로 인식해 또 그것에 대해 검색하고 외우는 공부에 시간을 투자하게된다.

이전 포스팅에서 짧막하게 자바스크립트라는 언어는 함수와 객체가 전부라고 말한것이 있다. 추후에 설명하는 날이 오겠지만 function도 사실은 Function의 객체이기때문에 '함수객체'라는 표현도 등장하게된다(깨알같이 첨언하자면 function은 Function의 리터럴 표현이다.). 그만큼 자바스크립트에서 객체는 중요하며 아무리 강조해도 넘치지않는다는것을 알리며 이번 포스팅을 마치겠다.

'Java Script & HTML' 카테고리의 다른 글

#07. JavaScript의 변수스코프  (0) 2015.09.22
#06. JavaScript의 new 와 생성자함수  (0) 2015.08.31
#05. JavaScript의 객체  (2) 2015.08.30
#04. JavaScript의 함수  (0) 2015.08.28
#03. JavaScript의 연산자  (0) 2015.08.27
#02. JavaScript의 Parsing - 02  (0) 2015.08.26
댓글
  • 프로필사진 ohnewdev 재미있게 잘 보고 있습니다~
    설명을 잘 해 주셔서 감사합니다.

    저기
    var obj = new Object();

    obj.name = "LichKing";
    obj.["getName"] = function(){
    return this.name;
    }
    부분은 크롬브라우저 콘솔에서 찍어보고 있는데요.
    Uncaught SyntaxError: Unexpected token [
    라고 오류가 납니다.
    2017.02.25 13:41
  • 프로필사진 LichKing 앞에있는 . 연산자때문에 났었네요 봐주시고 예제까지 실행해봐주셔서 감사합니다 ㅎㅎ 수정했습니다~! 2017.02.25 13:47 신고
댓글쓰기 폼