(10) 객체지향 클래스
ES2015 버전부터 자바스크립트에서 클래스를 사용할 수 있게 되었다. 자바스크립트는 객체지향 언어에 존재하는 class 구문이 없다. 대신, 객체 인스턴스를 활용하는 프로토타입 객체가 있다. ES2016부터 겉보기에 class 문법을 사용할 수 있지만 내부에 돌아가는 구조는 프로토타입 객체 방식이다. 하지만 이 마저도 IE 7이전 버전에는 적용되지 않는다. 향후 3~4년간 웹 브라우저가 완벽하게 ES2015문법에 적용하기 전까지는 기존의 프로토타입과 인스턴스 객체생성 방식을 알아둬야 할 필요가 있다.
1 『프로토타입』
프로토타입이란 뭘까? 사전적인 의미로는 '모형'이다. 어떠한 제품을 양산하기 위한 '시제품' 정도로 이해할 수 있다.
가령, 신발을 생산하는 공장을 짓는다면, 각 사이즈에 맞는 '틀'부터 만들어야 한다.(대량생산을 위해서) 발 모양과 사이즈, 디자인에 맞는 나무모형을 제작한 후에 가죽을 가열하여 신발모양을 만든다. 여기서 신발제작에 사용하는 '나무모형'은 자바스크립트에서 '프로토타입'정도로 생각할 수 있다.
다른 언어에서는 프로토타입을 '클래스'라 명하고, 클래스를 상속(복사)받은 후에 기능을 추가하거나 빼서 각 프로젝트에 맞는 객체를 생성한다.
ES2015버전이 도입되기 전까지, 자바스크립트에서는 클래스가 없었다. 이 때문에 프로토타입(모형)을 만들고, 이를 복사(인스턴스)하여 사용하였다. 사실상 프로토타입을 생성하고, 이용하는 것을 클래스를 이용하는 것이라 불러도 무방하다.
2 『클래스 정의』
[예제]
var Blogpost =
function(name,time ) {
this.name = name;
this.time = time;
this.conduct =
function( ) {
return this.name +
this.time;
}
};
var myBlog = new Blogpost( 'mogl3d' , '20171117 );
console.log( myBlog.conduct( ) );
myBlog.getTime( ) = function( ){
return this.time;
}
console.log( myBlog.getTime( ) );
// 결과: mogl3d20171117
// 결과: 20171117
프로토타입에서 인스턴스를 만들면, 각각의 객체에 따라 다른 복사본의 공간이 만들어진다.
[예제]
var Members = function( fistname, lastname
){
this.firstname = firstname;
this.lastname = lastname;
this.getName =
function( ){
return this.firstname + this.lastname;
}
}
var name1 = new Members( '이' , '예린'
);
console.log( name1.getName( ) ); // 결과: 이예린
var name2 = new Members( '황' , '수창'
);
name2.getName2 = function( ) { //
getName2 매서드 추가하기
return
this.firstname + this.lastname;
}
console.log( name2.getName2( ) ); // 결과: 황수창
console.log( name1.getName2( ) ); // Uncaught Type error
위의 코드에서 똑같은 프로토타입 객체 Members를 인스턴화한 객체들이 name1 과 name2이다. 하지만 name1과 name2는 Members 프로토타입을 참조만 하고 있을뿐, 각자 복사한 영역은 다르다.
가령, 특정 TV를 컨트롤 할 수 있는 리모콘이 2개 있는 상황이라면, 우리는 리모콘 조작을 통해 TV기능을 이용한다. 이때 리모콘(인스턴스 객체)으로 조작하는 TV(프로토타입 객체)는 같다고 할 수 있지만, TV가 같다고 리모콘도 같다고 할 수는 없다.
name1과 name2는 리모콘이다.
name2.getName2( )라는 매서드는 name2라는 리모콘에 새로 저장된
기능이다.
TV나 name1에서 아무리 getName2( ) 기능을 활용하려 해도 찾을 수
없다.
3 『프로토타입, this』
자바스크립트에서 this는 특별하다. 함수라면 함수 그 자신을 가리키고, 생성자나 객체 자신을 뜻하기도 한다. this는 이벤트, 메소드, 함수, 생성자에서 많이 사용되지만, 프로토타입에서 중요한 쓰임새는 call / apply 메소드에 있다.
call / appy 메소드는 둘 다 함수가 제공하는 멤버로, 그 함수를 호출한다.
call과 apply의 차이점은, 함수의 인수에 데이터를 건네는 방식에 있다.
call 메소드는 개별값으로 지정하는 데 반해 apply 메소드는 배열로 전달한다.
[예제]
var data = 'ALL'
var obj1 = { data : 'javascript' }
var obj2 = { data : 'node.js' }
function dev( ) {
console.log(
this.data );
}
dev.call ( null ); // 결과 : ALL
dev.call ( obj1 ); // 결과 'javascript'
dev.call ( obj2 ); // 결과 'node.js'
dev 함수의 console.log( ) 안에 this키워드가 있다. 여기서 this가 가리키는 값은 call 메소드에 의해 들어온 인수의 객체다. 따라서 call ( )인수값에 어떠한 객체가 오는지에 따라 this가 가리키는 값이 달라지고, console.log 결과값도 달라진다.
call( )메소드를 활용한 배열 예시를 살펴보자.
[예제]
function data( ) {
var args = Array.prototype.slice.call( arguments );
console.log(
args.join( '/ ' ) );
}
data( 'Angular' ,'Electron' ,'Meteor' ); // 결과: Angular/Electron/Meteor
위의 예제에서는 인수로 들어온 arguments값을 배열로 자른 후에 (slice) call 메소드를 활용하였다. 여기서 call메서드는 arguments 객체를 가리킨다.
* 참고사항:: 생성자 강제호출
방어
[예제]
var Members = function( firstName, lastName
){
this.firstName = firstName;
this.lastName =
lastName;
}
var name = Members( '조세' ,'무리뉴' ); // 'new'를 붙이지 않은 실수를 했다.
console.log(name); // 결과: undefined
console.log(firstName); // 결과: 조세
console.log(name.firstName); // 결과: Error
위와 같이 프로토타입을 인스턴스화 할 때 'new'를 빼먹는 실수를 할 수 있다. 이렇게 되면, firstName을 글로벌 변수로 인식해버린다. 따라서 반드시 아래처럼 생성자를 작성할 때 new를 붙여야 한다.
var Members =
function(firstName,lastName){
if( !(this
instanceof Members )) {
return new Members(firstName,lastName);
}
this.firstName = firstName;
this.lastName =
lastName;
};
'코드 스터디' 카테고리의 다른 글
자바스크립트 문법 (12) 객체의 상속(프로토타입 체인) (0) | 2019.05.16 |
---|---|
자바스크립트 문법 (11) 프로토타입 객체 (0) | 2019.05.15 |
자바스크립트 문법 (9) 클로저 (0) | 2019.05.13 |
자바스크립트 문법(8) 고차함수 (0) | 2019.05.07 |
자바스크립트 문법(7) 함수의 반환값 (0) | 2019.05.06 |
댓글