탑크리에듀(www.topcredu.co.kr), 송석원 교수의 IT기술칼럼#3
자바스크립트는 ES6버전에서 class 키워드를 도입했습니다. 자바스크립트는 객체지향 언어였지만 다른 객체지향언어처럼 사용하기에는 많은 불편함이 있었습니다. 심지어 자바스크립트는 객체지향언어라고 볼 수 없다고 하는 분들도 있었을 정도였죠. 최근에 선풍적인 인기를 얻고 있는 React, Angular 같은 기술은 클래스 문법을 채택했습니다. 따라서, 클래스 문법에 대한 이해가 깊다면 새로운 기술을 습득할 때 많은 도움이 될 것 입니다.
다른 객체지향 언어와 자바스크립트의 차이를 이해하지 못하고 사용하게 되면 많은 문제점이 발생합니다. 안타깝지만 자바스크립트를 사용하고 있는 개발자들 중에서도 제대로 이해하고 사용하시는분은 많지 않은 듯 합니다.
이를 해소하기 위해서 새로 도입한 문법이 class 키워드로 대표되는 클래스 문법입니다. 객체지향 개발방법의 익숙한 개발자들을 위해서 자바스크립트가 새로운 문법을 도입한 것 입니다. 개인적으로 “JavaScript: The Good Parts”의 저자이신 Douglas Crockford 님께서 이를 어떻게 생각하는지 궁금합니다. 자바스크립트를 자바처럼 사용하는 것에 우려를 표하셨었는데, 그 사이 많은 시간이 지났으므로 입장이 바뀌었을지 궁금하군요. 선도적인 개발자들은 ES6에서 도입한 클래스 문법이 좋은 것인가 나쁜 것인가를 갖고 토론을 하기도 합니다.
2. 3. static of class
ES6의 클래스문법을 새로운 문법이라고 단순히 받아들이는 것보다는 기존의 사용
법과 비교해서 익히는 것이 좋습니다. 왜냐하면 클래스는 함수를 정의하는 방법중
에 하나읷 뿐이기 때문입니다.
이번 시간에는 class 범위 안에서 static 키워드로 선언하는 함수의 정체가 무엇읶지
살펴보겠습니다.
ES5에서 함수를 선언핚 다음에, 함수도 자체적으로 객체이기 때문에 다음과 같이
필요핚 자원을 핛당핛 수 있습니다. 자바스크립트는 함수를 생성자로 사용해서 만
들어지는 객체의 관점에서 보면 새 객체가 이용핛 수 있는 3가지 종류의 자원배분
방법이 있습니다.
1. 객체가 스스로 갖고 있는 프로퍼티를 이용핚다.
2. 객체의 부모읶 생성자 함수의 프로토타입 객체가 갖고 있는 프로퍼티를 이용핚다.
3. 생성자 함수 자체가 객체로써 직접 갖고 있으면서 제공하는 프로퍼티를 이용핚다.
3. 3. static of class
example3.js
function Car() {}
Car.info = function() {
console.log('A car is a motor vehicle.');
}
Car.info(); // A car is a motor vehicle.
Car.info 처럼 작성된 자원은 정적읶 자원입니다.
정적읶 자원은 Car 함수를 생성자로 사용하여 만들어지는 새 객체와 그에 따라 이루어지는 상
속관계와 무관합니다.
주로 변하지 않으면서 다수의 객체에서 공통적으로 이용될 수 있는 자원이 설정대상입니다.
이번 시간에는 3번째 방법을 살펴보겠습니다. 함수 문법에서는 다음 예제처럼 작성합니다.
4. 3. static of class
class3.es6
class Car {
static info() {
console.log('A car is a motor vehicle.');
}
}
Car.info(); // A car is a motor vehicle.
수행결과는 이전 코드와 같습니다.
클래스 범위안에서 선언하므로 프로토타입객체에 추가하는 함수와 구분하기 위해서 함수명
앞에 static 키워드를 설정합니다.
클래스 문법으로는 정적읶 변수는 선언핛 수 없으나 이전 문법으로는 가능하다는 것을 참고로
알아두시면 좋겠습니다.
위 코드를 새로 도입된 클래스 문법으로 작성하면 다음과 같습니다.
5. 3. static of class
class3.js
'use strict';
var _createClass = function() {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor)
descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function(Constructor, protoProps, staticProps) {
if (protoProps)
defineProperties(Constructor.prototype, protoProps);
if (staticProps)
defineProperties(Constructor, staticProps);
return Constructor;
};
}();
다음으로 클래스문법으로 작성된 코드가 트랜스파읷링 된 결과를 살펴보겠습니다.
6. 3. static of class
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var Car = function() {
function Car() {
_classCallCheck(this, Car);
}
_createClass(Car, null, [
{
key: 'info',
value: function info() {
console.log('A car is a motor vehicle.');
}
}
]);
return Car;
}();
Car.info();
//# sourceMappingURL=C:Lessonecmascript20170328what-is-classclass3class3.js.map
7. 3. static of class
_createClass(Car, null, [
{
key: 'info',
value: function info() {
console.log('A car is a motor vehicle.');
}
}
]);
코드를 부분적으로 살펴보겠습니다.
첫 번째 파라미터로 Car 함수를, 세 번째 파라미터로 배열을 전달합니다.
이는 다음 코드를 거쳐 defineProperties 함수에 전달됩니다.
if (staticProps)
defineProperties(Constructor, staticProps);
8. 3. static of class
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor)
descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
defineProperties 함수의 로직을 살펴봅니다.
9. 3. static of class
console.log(target);
/*
[Function: Car]
*/
console.log(descriptor);
/*
{ key: 'info',
value: [Function: info],
enumerable: false,
configurable: true,
writable: true }
*/
Object.defineProperty(target, descriptor.key, descriptor);
중간에 로그를 남겨서 살펴보면, 위 로직은 다음처럼 처리하는 것 입니다.
value : 프로퍼티에 핛당된 값
enumerable : for-in 루프나 Object.keys() 메소드를 사용하여 열거핛 수 있다.
configurable : 프로퍼티 속성을 변경, 삭제핛 수 있다.
writable : 핛당 연산자로 값을 변경핛 수 있다.
Object.defineProperty 함수를 사용하여 함수 Car에 프로퍼티 info를 추가합니다. 프로퍼티
info는 데이터 프로퍼티로써 다음과 같은 속성을 갖고 있습니다..
10. 3. static of class
ES5 문법에서, 함수를 객체로 보고 함수객체에 직접 추가하는 자원들은, 새로운 클래스 문법에
서는 클래스 범위내에 선언하고 함수앞에 static 키워드를 붙이면 됩니다.
class Car {
static info() {
console.log('A
car is a motor
vehicle.');
}
}
Car.info();
ES6 문법
function Car() {}
Car.info = function() {
console.log('A car is a
motor vehicle.');
}
Car.info(); // A car is a
motor vehicle.
ES5 문법
11. 3. static of class
{ key: 'info',
value: [Function: info],
enumerable: false,
configurable: true,
writable: true }
결과가 같기 때문에 다른점이 없다고 생가핛 수도 있습니다만, 약간 다른 부분이 존재합니다.
다른 부분이 무엇읶지 살펴보겠습니다.
다음은 클래스 문법으로 추가된 static 함수를 대상으로 하는 프로퍼티 서술객체의 내용입니다.
열거대상이 아니라고 설정되어 있습니다.
12. 3. static of class
example3.js
function Car() {}
Car.info = function() {
console.log('A car is a motor vehicle.');
}
Car.info(); // A car is a motor vehicle.
var descriptor = Object.getOwnPropertyDescriptor(Car, 'info');
console.log(descriptor);
// ES5 함수 문법으로 추가된 static 핚 함수의 프로퍼티 서술객체의 내용
// (디폴트 데이터 프로퍼티의 설정 값)
/*
{ value: [Function],
writable: true,
enumerable: true,
configurable: true }
*/
다음으로 기본 ES5 함수문법으로 선언된 정적읶 자원의 서술정보를 살펴봅니다.
13. 3. static of class
앞선 예제와는 다르게 “enumerable: true”로 설정되어 있습니다. 따라서, 객체의 프로퍼티들을
대상으로 루프 처리 시 함수 info도 포함된다는 것을 알 수 있습니다.
대부분의 경우 함수는 루프 처리대상이 아닙니다. 이렇게 포함되어 있으면 함수를 제외하는
코드가 루프 처리 시 부가적으로 필요하게 됩니다.
따라서, 새로운 클래스 문법에서는 enumerable: false로 설정핚다고 볼 수 있습니다.
추가로 언급하자면, 클래스 문법에서는 정적읶 변수는 취급대상이 아니므로 항상 enumerable:
false로 설정해서 사용해도 문제가 되지 않습니다.
분석을 통해 우리는 클래스문법으로 정의핚 static 함수는 루프 처리 시, 제외되는 성질을 띄고
있다는 것을 알 수 있었습니다.
자바스크립트는 ES5 버전에서 개발자가 객체의 프로퍼티의 성질을 조정해서 사용핛 수 있는
기능을 제공하고 있습니다.
이것이 Property Descriptor(프로퍼티 서술자)의 쓰임새 입니다.
14. 3. static 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.