1. { for AngularJS, React}
고급 자바스크립트
2. prototype of class
탑크리에듀
IT기술 칼럼
와 함께하는
2. { ES6 }2. prototype of class
먼저, ES5문법에서 사용하던 방식을 살펴보겠습니다.
Car 함수를 선언합니다. 그 후에, 함수가 갖고 있는 히든 프로퍼티 prototype이
가리키는 객체에 동적으로 say라는 프로퍼티를 추가하고 이 것이 함수를 가리키게 합니다.
이렇게 하면 함수를 생성자로 사용하여 만들어지는 객체는 say함수를 이용할 수 있습니다.
바로, 자바스크립트의 프로토타입 체이닝을 통해 부모로부터 상속받는 자원을
이용하는 모습입니다.
example2.js
function Car(){}
Car.prototype.say =function() {
console.log('Hi');
}
let car =new Car('A');
console.log(car); // {}
car.say(); // Hi
3. { ES6 }2. prototype of class
그런데, 함수를 선언한 다음에 상속 자원(변수, 함수)을 설정하는 모습이 낯설기도 하고
깜박 잊고 설정하지 않을 수도 있겠지요.
이를 클래스 문법으로 변경하면 함수의 프로토타입 객체에 추가되는 자원도
클래스 범위 안에서 설정합니다.
이렇게 하면, 범위 구분이 확실해서 좋고 기존 자바 개발자들도 클래스를 작성하는 방법이
친숙하게 느껴져서 쉽게 작성할 수 있을 것 입니다.
다음 예제를 살펴보면서 얘기를 나눠보겠습니다.
class2.es6
class Car{
say() {
console.log('Hi');
}
}
let car =new Car();
console.log(car); // {}
car.say(); // Hi
4. { ES6 }2. prototype of class
example2.js와 class2.es6의 코드는 결과적으로 같은 로직을 수행하는 코드입니다.
클래스 문법에서는 클래스의 프로토타입 객체에 추가하는 자원을 클래스 범위 내에서 일반적
인 함수처럼 선언합니다.
클래스 문법에서는 프로토타입 객체에 변수를 추가하는 방법은 지원하지 않습니다.
이를 수행하고자 원한다면 Car.prototype 객체에 직접 추가하는 방법을 사용해서 구현할 수 있
습니다. 클래스는 함수이므로 다음처럼 작성하면 됩니다.
class2.es6
class Car{
say() {
console.log('Hi');
}
}
let car =new Car();
console.log(car); // {}
car.say(); // Hi
console.log(car.number); // undefined
Car.prototype.number = 7;
console.log(car.number); // 7
5. { ES6 }2. prototype of class
다음으로 example2.es6 파일을 트랜스파일링한 결과코드를 살펴보겠습니다.
class2.js
'usestrict';
var_createClass= function(){
functiondefineProperties(target,props){
for(vari= 0;i <props.length;i++){
vardescriptor=props[i];
descriptor.enumerable=descriptor.enumerable|| false;
descriptor.configurable= true;
if("value"in descriptor)
descriptor.writable= true;
Object.defineProperty(target,descriptor.key,descriptor);
}
}
returnfunction(Constructor,protoProps,staticProps){
if(protoProps)
defineProperties(Constructor.prototype,protoProps);
if(staticProps)
defineProperties(Constructor,staticProps);
returnConstructor;
7. { ES6 }2. prototype of class
varcar= newCar();
console.log(car);//{}
car.say();//Hi
console.log(car.number);
Car.prototype.number=7;
console.log(car.number);
//#sourceMappingURL=C:Lessonecmascript20170328what-is-classclass2class2.js.map
코드를 부분적으로 살펴보는 것이 좋겠습니다. : )
var Car = function() {
function Car() {
_classCallCheck(this, Car); // 생성자로 사용되고 있는지 체크한다.
}
_createClass(Car, [
{
key: 'say',
value: function say() {
console.log('Hi');
8. { ES6 }2. prototype of class
}
}
]);
returnCar;
}();
함수를 선언하면서 즉시 실행하고 있으므로 “var Car”가 할당받는 결과는 “return Car;” 코드에
따라서 지역함수인 Car입니다. 이 때 지역함수 Car는 필요한 작업이 수행된 함수입니다.
어떤 작업을 수행한 후에, 지역함수 Car를 리턴하는지 살펴보겠습니다.
_createClass(Car,[
{
key:'say',
value:functionsay(){
console.log('Hi');
}
}
]);
_createClass 함수의 파라미터로 다음 데이터를 전달하고 있습니다.
9. { ES6 }2. prototype of class
var_createClass= function(){
functiondefineProperties(target,props){
for(vari= 0;i <props.length;i++){
vardescriptor=props[i];
descriptor.enumerable=descriptor.enumerable|| false;
descriptor.configurable= true;
if("value"in descriptor)
descriptor.writable= true;
Object.defineProperty(target,descriptor.key,descriptor);
}
}
returnfunction(Constructor,protoProps,staticProps){
if(protoProps)
defineProperties(Constructor.prototype,protoProps);
if(staticProps)
defineProperties(Constructor,staticProps);
returnConstructor;
};
}();
_createClass가 가리키는 함수는 어떤 상태인지 살펴봅니다.
10. { ES6 }2. prototype of class
returnfunction(Constructor,protoProps,staticProps){
if(protoProps)
defineProperties(Constructor.prototype,protoProps);
if(staticProps)
defineProperties(Constructor,staticProps);
returnConstructor;
};
함수를 선언한 후 즉시실행하고 있으므로 _createClass가 가리키는 함수는 다음과 같습니다.
_createClass(생성자함수,프로토타입객체에추가될자원,생성자함수객체에직접추가될정적인자원)
이 때, 전달되는 파라미터의 존재여부에 따라서 기동하는 함수 defineProperties 함수는
외부 스코프에 있으므로 클로져가 됩니다. 위 코드를 정리하면 다음과 같습니다.
if(protoProps)
defineProperties(Constructor.prototype,protoProps);
현재, 프로토타입객체에 추가될 자원만 존재하므로, 다음 조건만이 만족됩니다.
11. { ES6 }2. prototype of class
첫번째파라미터:Car.prototype,
두번째파라미터:
[
{
key:'say',
value:functionsay(){
console.log('Hi');
}
}
]
Object.defineProperty 메소드는 target객체에 새 프로퍼티를 정의하거나 기존 프로퍼티를 수
정하는 메소드입니다.
결과로 수정된 객체를 리턴하는데 여기서는 리턴 값을 사용하고 있지는 않고 있습니다.
Constructor.prototype, protoProps으로 전달되는 파라미터의 실체를 환원해서 살펴보면
다음과 같습니다.
12. { ES6 }2. prototype of class
functiondefineProperties(target,props){
for(vari =0;i <props.length;i++){
vardescriptor= props[i];
console.log(descriptor);//{key:'say',value:[Function:say]}
descriptor.enumerable=descriptor.enumerable||false;
console.log(descriptor.enumerable);//false
결국, defineProperties 함수는, 두 번째로 받은 배열의 길이만큼 루프를 돌면서, 필요한 설정을
수행한 다음 Object.defineProperty 함수를 통해 Car.prototype 객체에 프로퍼티를 추가하는
코드입니다.
14. { ES6 }2. prototype of class
앞서 살펴 본 내용을 간단하게 표로 정리해 보겠습니다.
classCar{
say(){
console.log('Hi');
}
}
letcar= newCar();
console.log(car);//{}
car.say();//Hi
ES6 문법
functionCar(){}
Car.prototype.say=function(){
console.log('Hi');
}
letcar= newCar('A');
console.log(car);//{}
car.say();//Hi
ES5 문법
15. { ES6 }2. prototype of class
이번 시간에 살펴 본 주인공은 클래스 범위안에 정의하는 함수였습니다.
ES5 문법에서는 함수를 만들고 난 후, 추가로 상속용 객체에 함수를 정의했다면 ES6 문법에서
는 클래스 범위연산자 안에서 함수를 정의한다는 문법적인 차이만 있을 뿐, 결과적으로 처리
되는 방법은 똑같다는 것을 알 수 있었습니다.
클래스문법으로 작성해도 실체는 함수이므로 기존의 함수문법과 섞어서 사용하는 것이 가능
하고 이는 매우 자연스러운 모습이라는 것을 기억하시면 좋겠습니다.
16. { ES6 }2. prototype of class
송석원
현재 :
- 탑크리에듀교육센터 자바, 스프링 프레임워크, JPA, Querydsl,
AngularJS, React, Android 분야 전임강사
경력 :
- 오라클자바커뮤니티교육센터
자바, 스프링, JPA, Node.JS, AngularJS, React, Android 전임강사
- 탑크리에듀 교육센터
Java, Spring Data JPA, Querydsl, SQL 교재 편찬위원
- 회원수 14,000명의 오라클자바커뮤니티 운영 및 관리
- SK T-아카데미 스프링 프레임워크 강의
- 정철 어학원
탑크리에듀교육센터 Tel. 02-851-4790 http://www.topcredu.co.kr
Copyrights ⓒ Topcredu. All rights Reserved.