0%

자바스크립트의 객체 생성방법 3가지

1.객체 리터럴을 이용한 객체 생성 방식

리터럴 방식 객체생성은 하나의 객체를 그 즉시 생성한다.
거두절미하고 소스와 주석으로 객체 리터럴을 설명하겠다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var filmograyphyList = ['도날드덕', '환타지아']; // 배열 객체를 선언한다.

var man = {}; // 비어있는 프로퍼티가 없는 리터럴로 man 이라는 객체를 생성

//duck 이라는 이름의 객체를 객체리터럴을 통해 생성한다.
var duck = {
//객체 내부에는 그 객체의 특징(element)이 되는 프로퍼티를 여러개 갖을수 있으며
//이 프로퍼티에는 자바스크립트에 존재하는 모든 것을 담을수 있다.(원시값을 포함해 함수, 배열 ...)
name: '도날드 덕',
age: 82,
sex : man, // 프로퍼티에 객체가 할당된다.
별명 : '도날드 트럼프', // 자바스크립트 프로퍼티명은 영어가 아닌 한글도 가능하다.

filmograyphy : filmograyphyList, // 프로퍼티에 객체배열을 할당한다.

'home adress' : '디지니 랜드', // 일반적으로 프로퍼티 명을 뛰어 쓰기로 사용할수 없으나
//예외적으로 싱글쿼티션(') 또는 더블쿼티션("")으로 감싼 프로퍼티명은 사용이 가능하다.
// 프로퍼티 네이밍은 일반적으로 자바스크립트 변수 네이밍
//규칙을 따른다.(ex:숫자로 시작하는 변수명은 사용할수 없다.)
// 하지만 싱글쿼티션(') 또는 더블쿼티션("")으로 감싼 프로퍼티명은 이런 자바스크립트의 //변수명 작성 규칙 제한을 받지 않는다.

for : 'test2222', // for, if 등 시스템 예약어는 변수명으로는 사용할수 없다 하지만 자바스크립트
//객체프로퍼티명으론 사용할수 있다.
'if' : 'test111', // 하지만 이런 예약어들의 사용을 권장하지 않으며, 만약 불가피 하다면 문자열로
//감싸 사용하길 권장한다.

//프로퍼티에는 함수또한 담길수 있으며, 특이하게 객체의 프로퍼티중 함수를 담고 있는 프로퍼티는 메소드라고 부른다.
say : function(){
console.log('꽥 꽥');
}

};

리터럴이라는 말을 위키피디아에서 찾아보니 컴퓨터 과학분야에서, 소스코드의 고정된 값을 대표하는 용어라고한다.( 즉 객체 리터럴 방식은 객체를 생성하는 표기법 정도로 이해하고 넘어가자. 리터널에 대해서는 인터넷에 한번 찾아보길 바란다.)

위 소스는 obj1이라는 이름의 객체를 리터럴 방식으로 생성한 것이다.
객체 리터럴은 중괄호 { } 를 이용하여 프로퍼티명과 프로퍼티의 값을 감싼 형태로 생성 된다.
{ ‘프로퍼티이름’ : ‘프로퍼티값’ }

더 자세한 내용은 위의 동영상을 참고하길 바란다.

2.생성자를 이용한 객체 생성

생성자 함수를 이용해 반복적으로 동일한 형태(프로퍼티를 갖는)객체를 생성하는 일반적인 방법.

일단 자바스크립트의 생성자란 객체를 반복적으로 생성할수 있는 함수이다.
대중적인 객체지향 언어인 java, c++ 같은 언어에서는 class라는 객체의 설계도 내부의 생성자라는 함수를 가지고 있는데, 자바스크립트에서는 클래스라는 객체의 설계서가 따로 존재하지 않으며 이 생성자 내부에서 객체의 설계내용을 작성한다.

그리고 자바스크립트에서는 기본적인 함수와 생성자간의 문법적 구별이 없다. A라는 함수가 있다면 이것을 그냥 함수처럼 호출할수도 있고, new라는 키워드로 생성자로 호출할수도 있다.

역시 거두절미하고 소스를 보자.

1
2
3
4
5

var obj1 = new Object(); // 자바스크립트에 내장된 기본 Object 생성자를 이용해 빈 객체를 생성.
var arrayObj1 = new Array(10); // 자바스크립트에 내장된 기본 Array 생성자를 이용해 빈 배열 객체를 생성.
var dateObj1 = new Date(); // 자바스크립트에 내장된 기본 Date 생성자를 이용해 날짜 정보를 담은 Date 객체를 생성.
// Object, Array, Date 뿐만아니라 여러 다른 기본 내장 객체 생성자가 존재한다.

위처럼 내장된 생성자 객체들을 이용하여 객체를 생성할수 있다.
이런 내장된 생성자 말고 프로그래머가 직접 원하는 객체를 생성할수 있도록 생성자를 만들수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//Duck이라는 생성자를 만든다. 자바스크립트에서는 일반 함수와 생성자의 문법적 차이가 없다.(개인적으로 불만이다.)
//생성자와 함수를 구별하기 위해 보통 생성자의 이름은 대문자로 선언한다.
function Duck(dName, dAge){

//생성자 함수의 내부에 있는 this라는 키워드는 이 함수가 new로 호출되었을때 생성해서 리턴하는 객체를 가리키며
//this.name은 그 생성될 객체의 프로퍼티를 생성하겠다라는 의미이다.

this.name = dName; // 생성자 함수를 호출시 전달받는 전달인자를 name이라는 프로퍼티에 할당한다.
this.age = dAge; // 생성자 함수를 호출시 전달받는 전달인자를 age이라는 프로퍼티에 할당한다.
this.종 = '오리';

//객체 리터럴과 다르게 아래처럼은 객체 프로퍼티의 프로퍼티명을 문자열로 만들수 없다.
//this."home adress" = '디지니 랜드';

//하지만 이런식으로 객체가 유사배열인 것을 이용하여, 배열 형태로 프로퍼티를 생성할 시 문자열로 프로퍼티명을 생성할수 있다.
this["home adress"] = '디지니 랜드';

this.for = '하하하?';

this.say = function(){
console.log('꽥 꽥');
};

}// Duck end

자 위 소스로 객채를 생성할수 있는 함수 즉 생성자를 선언했다.
이제 위 생성자를 통해 객체를 생성해 보자.

1
2
3
4
5
6
//new 라는 키워드의 의미는 new 다음에 올 함수를 생성자로서 호출하겠다는 의미이다.
//여기서 중요한 것은 new로 호출된 모든 함수는 객체를 반드시 생성해서 리턴하게 된다.
//생성자는 어떤 형태의 객체를 만들 목적으로 만들어 진 것일뿐 일반함수와 같다.
var duck1 = new Duck('도날드 덕', 82);

console.dir(duck1);

생성된 객체를 console.dir로 열어보면 Duck생성자로 생성된 객체의 프로퍼티를 확인 할 수 있다.

일단 생성자를 하나 만들었다면,

1
2
var duck2 = new Duck('레임 덕', 5);
var duck2 = new Duck('베이징 덕', 3);

이처럼 반복적으로 객체를 생성하는 것이 가능하다.

지금 설명하는 생성자를 사용하여 객체를 생성하는 이유는 동일 형태의 객체를 반복적으로 생성할 수 있기 때문이다.
(물론 필요에 따라 객체리터럴로 객체를 생성해도 된다. 뭐가 좋고 나쁘다는 말이 아니다.)

자바스크립트에서 생성자가 다른 객체지향 언어와 개념적 차이가 있는데, 일반적인 객체지향언어에서 클래스라는 개념이 있다.
이 클래스라는 개념은 객체의 설계도 역할을 한다. 예를 들어 객체가 가져야 할 프로퍼티들을 정의 하는데, 자바스크립트에서는 이 클래스라는 개념이 없으며,그 대신 자바스크립트에서 생성자에서 this.프로퍼티명 을 이용하여 이 클래스의 설계도와 같은 기능을 포함하고 있다.

  1. Object.create 매소드를 이용해한 객체 생성

자바스크립트의 객체의 상속을 따라가다보면 최상위 객체가 존재하신다.(필자는 god object라고 장난스래 부른다)
그리고 이 최상위 객체를 이용하여 자바스크립트에서 객체를 생산하시는 성모마리아님 같은 최상위 생성자(자바스크립트 내장 상성자)가 역시 존재하는데, 그 분이 Object()생성자 이시다.
이 Object생성자 객체의 create 메소드를 이용하면, 객체 생성과 동시 객체 상속을 조금더 손쉽게 할수 있다.
이 기능은 ecma5(이끄마파이브) 부터 지원하며, 자세한 내용은 아래 MDN을 참고!

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/create

절대 귀찮아서 Object.create 설명은 글로 안쓴것이 아니다. 솔직히 나도 잘 모ㄹ…. 콜록콜록

자바스크립트에서 객체란?

일단 자바스크립트는 객체지향 언어이고, 객체란 일종의 숫자, 문자열과 같은 데이터 형태 중 하나이다.

자바스크립트의 객체를 설명하기 앞서 객체(Object:오브젝트)라는 말을 간단히 설명하고 가겠다. (이미 안다면 그냥 넘어가시길…)
프로그래밍 영역에서 객체(Object:오브젝트) 어떤 의미일까?
영어로는 물건, 물체등으로 해석된다.
컴퓨터 용어의 Object도 영어의 그것과 크게 다르지 않다.

사람은 어떤 물건, 예를들어 자동차와 같은 물체를 인식(or이해)할 수 있다.
예를 들어 아래의 자동차를 차에대해 전혀 모르는 친구에게 설명해본다고 하자.


>![](/images/2017-06-11-javascript3_1.JPG)

이 차의 회사는 쉐보레이고, 차종은 카마로 범블비 에디션이고, 색상은 노란색이며, 바퀴는 4개 달려있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var car1 = {
company: '쉐보레',
wheels: 4,
color: '#FFE400', //노란색 RGB 색상표
name : '카마로 범블비 에디션',
'배기량' : '5000',
transform : function(){
console.log('범블비로 변신');
},
run : function(){
console.log("범블비 달린다!");
}
};

function do_something(car1); // 이차로 무언가 해봐!, 분해를 하던, 폐차를 하던

당신이 자바스크립트에서 변수라는 것을 알고 있다면 car1 이라는 것이 카마로라는 자동차의 설명 정보를 담고 있다는 것을 어렴풋이 느낄수 있을것이다. 그리고 do_something 이라는 함수에 car1 을 전달인자로 넘겨 버렸다.
위 소스의 car1이 자바스크립트에서 객체이다.

쉽게 말해서 프로그래밍 영역에서 객체란 어떤 대상의 복합적인 데이터를 담고 있는 데이터이다.
당신이 알고 있는 어떤 무언가(대상)를 다른 사람에게 설명하듯이 컴퓨터에게 그것들을 인식시키기 위해 그 대상의 특징(element)를 만들고 그 특징에 대한 설명정보를 담고 있는 것, 그것을 객체라고 부른다.
그리고 보통 이 객체라는 단위의 자료형(type)을 가지고 있는 프로그래밍 언어를 객체지향언어(객체라는 개념과 객체지향 프로그래밍을 지원)라고 부른다.
그리고 자바스크립트는 객체를 지원하는 객체지향 언어이다.

자바스크립트의 객체의 특징

  • 자바스크립트 객체는 프로퍼티를 갖는다. 그리고 프로퍼티는 데이터프로퍼티와 접근자프로퍼티 두 종류가 있다.
  • 자바스크립트 객체는 메소드를 갖는다.
  • 숫자, 문자열, 불린값, null, undefined 같은 기본 타입을 제외한 모든 값은 객체다. (함수, 배열, 정규표현식 등)
  • 클래스라는 개념이 없다.(java, c++와의 객체와 약간 생성, 사용방법이 다르다.)
  • 자바스크립트 객체는 참조타입이다.

함수호이스팅(Function Hoisting)

자바스크립트 영역에서 유명한 더글라스 클락포드는 함수를 생성할 때 선언식보다는 함수 표현식만을 사용할 것을 권고 하고 있다.
그 이유가 이 함수호이스팅 때문이라고 설명하는데, 대체 함수호이스팅 이란 무엇일까?

함수호이스팅의 = 함수 선언문으로 생성된 함수가 해당 소스코드의 유효범위의 맨 위로 끌어올려진다.

일단 소스코드를 보자

예제1(함수 선언문)

1
2
3
4
5
6
7
8
fn_test(1); //a호출:함수 선언문 이전에 호출

//함수 선언문
function fn_test(temp){
console.log('fn_test run... temp:'+ temp);
}

fn_test(2); //b호출:함수 선언문 이후에 호출

예제1 결과

만약 자바스크립트의 함수호이스팅을 모른다면 예제1의 결과를 의아하게 볼 수 있다.
a호출에서 아직 선언되지 않은 시점에서 fn_test함수를 호출 한 결과 오류가 발생하기는 커녕 정상적으로 함수가 호출되어 동작 했다.

이런 동작의 이유가 함수 호이스팅이다.
비록 함수선언문으로 생성된 함수 fn_test는 자동으로 소스코드 최상단으로 끌어올려진다.(a호출 보다 위로)

예제1의 함수호이스팅 동작의 상상

1
2
3
4
5
6
7
8
//함수 선언문, 소스코드 최상단으로 끌어 올려짐
function fn_test(temp){
console.log('fn_test run... temp:'+ temp);
}

fn_test(1); //a호출:함수 선언문 이전에 호출

fn_test(2); //b호출:함수 선언문 이후에 호출

즉 예제1은 위 소스와 같은 동작을 한다는 것이다.
함수 선언문은 함수 호이스팅에의해 항상 소스의 최초시점에 호출 되기때문에 호출a에서 fn_test가 정상 동작 한 것이다.

얼핏 보면 함수호이스팅은 편리한 기능처럼 보이기도 하다.
“어쨋든 오류는 없이, 소스코드가 동작하는데 편리한 기능 아닌가?”라고 생각 할 수도 있다.

마이클 더글락스는 함수 선언문은 소스코드를 엉성하게 만들어, 코더의 의도하지 않는 소스의 동작을 야기하기 때문에 지양해야 한다고 한다.
그리고 함수 선언문 대신 함수호이스팅이 발생 하지 않는, 함수 표현식으로 함수를 생성해서 사용 할 것을 권고 한다.

예제2(함수 표현식)

1
2
3
4
5
6
7
fn_test(1);  // a 호출: 함수 표현식 이전 호출

var fn_test = function(temp){
console.log('fn_test start… temp:' + temp);
};

fn_test(2); // b 호출: 함수 표현식 이후 호출

예제2 결과

예제1 함수 선언식과 다르게 함수 표현식으로 선언된 함수는 함수호이스팅이 발생하지 않으므로, 함수 생성 이전에 호출 할 경우 아직 존재하지 않는 함수를 호출게 되므로 오류가 발생한다.

개인적으로 화면 단 에서 간단한 DOM제어용 함수는 선언문으로 사용해도 상관 없지만, nodeJS나 Angular등 복잡하고 많은 분량의 자바스크립트 코드 개발시에는 더글라스 말대로 함수 표현식을 사용 하는것이 적당한 것 같다.

자바스크립트 책을 보다보면, 입급객체, 일급함수이런 말들이 나온다.

자바스크립트의 객체는 일급객체이다.
자바스크립트의 함수는 일금함수이다.

이게 대체 무슨 말일까?
어려워 할 것 없다. 이미 아는 것이지만, 단어가 생소해서 혼동이 올 뿐이다.

1급시민(일급시민:first class citizen)

: 일급객체, 일금함수 이런 말 이전에 일급시민이라는 말 부터 정리해 보도록 하자. 그 이유는 일급객체는 일급시민인 객체를 말하며, 일급함수는 일급시민인 함수를 말하기 때문이다.

일급시민을 간단히 말하자면 차별받지 않고 시민으로서 누릴수 있는 권한을 모두 누릴수 있는 사람을 일급시민이라고 한다.

  • 1급 시민은 투표권이 있다.
  • 1급 시민은 군인이 될 수 있다.
  • 1급 시민은 정치에 참여 할 수 있다.

1800년데 영국에서는 1급시민, 2급시민이 존재 했으며 성인 남성의 경우 1급시민으로서 정치참여가 가능한데 반해, 2급시민인 여성은 정치 참여를 할 수 없었다고 한다.

1급시민 이라는 말은 권한을 많이 누리는 대상이라고 볼 수 있다.

프로그래밍 영역에서 1급시민이란?

: 일단 프로그래밍 영역에서 1급시민을 정의하려면 1급시민이는 것들이 누려야할 권한이 뭔저 정의가 되어 있어야 한다.(실제 투표권 같은 권한 말이다.)

  • 1급 시민은 함수의 인자가 될 수 있다.
  • 1급 시민은 함수의 리턴이 될 수 있다.
  • 1급 시민은 변수에 할당 될 수 있다.

프로그래밍 영역에서 위와 같은 권한을 누리는 것들을 보통 일급시민이라 여긴다. 즉 자바스크립트에서 원시값(일반 자료형)은 1급 시민이다.

1
2
3
4
5
6
7
var temp_int = 1; // 숫자는 변수에 담긴다.
function fn_test_int(a){
return a;
}

var ret_int = fn_test_int(3); // 숫자는 함수의 인자가 된다.
console.log(ret_int); // 숫자는 함수의 리턴이 된다.

1급객체(일급객체:first class object)

자바스크립트의 객체는 1급객체이다.

라는 말은 자바스크립트에서 객체는 1급시민이 누리는 권한을 모두 가지고 있다는 말이다.
따라서 자바스크립트의 객체도 원시값 처럼 다음과 같다.

  • 자바스크립트의 개체는 함수의 인자가 될 수 있다.
  • 자바스크립트의 객체는 함수의 리턴이 될 수 있다.
  • 자바스크립트의 객체는 변수에 할당 될 수 있다.
1
2
3
4
5
6
7
8
var temp_obj = { name :'first class object1'};   // 객체는 변수에 담긴다.

function fn_test_obj(obj){
return obj;
}

var ret_obj = fn_test_obj(temp_obj); // 객체는 함수의 인자가 된다.
console.dir(ret_obj); // 객체는 함수의 리턴이 된다.

1급함수(일급함수:first class function)

자바스크립트의 함수는 1급함수이다.

라는 말은 자바스크립트에서 함수역시 1급시민이 누리는 권한을 모두 가지고 있다는 말이다.따라서 자바스크립트의 함수도 원시값 처럼 다음과 같다.

  • 자바스크립트의 함수는 함수의 인자가 될 수 있다.
  • 자바스크립트의 함수는 함수의 리턴이 될 수 있다.
  • 자바스크립트의 함수는 변수에 할당 될 수 있다.
1
2
3
4
5
6
7
8
9
10
var fn_outer = function(){
console.log('fn_outer 함수 동작...');
return function(){
console.log('리턴되는 함수가 동작...');
};
};

var ret_fn = fn_outer();
ret_fn(); // fn_outer함수의 리턴된 함수가 실행된다. 즉 함수는 함수의 리턴이 될수있다.
ret_fn();

java의 예외처리 내용이 햇갈려서 간만에 java책을 들여다보니 내가 몰랏던 기능들이 있어서 정리해 본다.

1.멀티 catch 구문 a.하나의 catch 블록에서 여러개의 Exception을 잡아서 처리하는 구문이다.

예제1-a

1
2
3
4
5
try{
// ...
}catch(AException a | BException b){
//...
}

자바 7부터 추가된 기능이라고 한다.

자동리소스 닫기(try-with-resources)

a.기존의 try-catch-finally 로 처리하던 관용적인 리소스(db 커넥션, 소켓 등등) 반납 로직을 간편하게 처리하기 위해 나온듯 하다.

b.자동리소스 닫기(try-with-resources)는 코드의 예외 발생 여부와 상관 없이 사용중인 리소스 (각종 입출력 스트림, 서버소켓, 소켓, 각종 채널)의 close() 메소드를 자동으로 호출하여 안전하게 리소스를 반납해준다.

예제 2-b

1
2
3
4
5
6
7
8
9
10
11
try(AStream as = new AStream()){
// 한개의 리소스 사용시
}catch(IOException e){
//...
}

try(AStream as = new AStream(); BStream as = new BStream();){
// 복수 개의 리소스 사용시
}catch(IOException e){
//...
}

기존의 finally를 이용하여 리소스를 클로즈 하는 행위를 자동으로 처리해주는 편리하느 기능이라고 생각 된다.

c. 자동리소스 닫기(try-with-resources)를 사용하기 위해서는 조건이 있다. AutoCloseable이라는 인터페이스를 구현한 리소스객체만 자동리소스 닫기(try-with-resources)를 적용 할 수 있다