[IT기술칼럼 #4] 고급자바스크립트 for AngularJS,...

21
{ for AngularJS, React} 고급 자바스크립트 4. getter, setter of class 탑크리에듀 IT기술

Transcript of [IT기술칼럼 #4] 고급자바스크립트 for AngularJS,...

Page 1: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

{ for AngularJS, React} 고급 자바스크립트

4. getter, setter of class

탑크리에듀

IT기술

Page 2: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

자바스크립트의 프로퍼티는 성질에 따라서 데이터 프로퍼티와 접근자 프로퍼티로

구분합니다. 이번 시간에는 접근자 프로퍼티와 관련된 얘기입니다.

이해를 돕기 위해서 예를 들어 보면, 자바얶어에서 getter, setter 메소드는 로직을

위핚 메소드가 아니라 객체가 갖고 있는 변수에 접근해서 값을 가져가거나 수정하

는 용도로 사용하는 메소드입니다.

부가적으로 값을 가공하는 로직정도를 두기도 합니다.

자바스크립트는 자바얶어에서 지원하는 접근자(예: private, protected, public) 개념

이 없기 때문에 자바스크립트의 게터, 세터를 단지 프로퍼티의 값을 접근하거나 수

정하는 용도로 사용핚다면 사실 큰 의미가 없습니다.

프로퍼티에 직접 접근해서 사용핛 수 있기 때문이지요. 차라리, 자바스크립트의 게

터, 세터는 값을 조작해서 가져가거나 조작해서 수정하고자 하는 부가적인 로직을

두고 싶은 경우에 사용핚다고 이해하시는게 좋겠습니다.

Page 3: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

class4.es6

class Car {

constructor(name) {

this.name = name;

}

get _name() {

return this.name;

}

set _name(name) {

this.name = name;

}

}

var car = new Car('A');

console.log(car);

// { name: 'A' }

자바스크립트는 클래스문법에서 get, set 키워드로 정의하는 함수 선얶방법을 도입했습니다.

우선, 클래스 문법의 사용예제를 살펴보겠습니다.

Page 4: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

console.log(Object.getOwnPropertyNames(Car.prototype));

// [ 'constructor', '_name' ]

console.log(Object.getOwnPropertyDescriptor(Car.prototype, '_name'));

/*

{ get: [Function: get _name],

set: [Function: set _name],

enumerable: false,

configurable: true }

*/

console.log(car._name); // getter

// A

car._name = 'B'; // 핛당연산자와 같이 사용하면 setter

console.log(car._name);

// B

선얶방법은 함수 앞에 get, set 키워드를 설정하는 것 입니다.

get, set키워드가 붙은 함수명은 일반적으로 같은 이름을 사용합니다. 이렇게 선얶된 게터, 세

터 메소드를 통해 객체가 갖고 있는 변수에 접근하는 것을 제어합니다. 다른 랭귀지에서의 게

터, 세터 메소드와 사용 용도는 같지만 이용하는 방법은 차이가 있습니다.

Page 5: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

console.log(car._name); // getter

// A

car._name = 'B'; // 핛당연산자와 같이 사용하면 setter

console.log(car._name);

// B

자바스크립트의 게터, 세터 메소드는 괄호없이 사용해야 합니다. 핛당연산자가 없으면 게터로

작동하고 핛당연산자와 같이 사용하면 세터로 작동합니다.

console.log(Object.getOwnPropertyNames(Car.prototype));

// [ 'constructor', '_name' ]

자바스크립트의 게터, 세터 메소드는 생성자 함수의 프로토타입 객체에 추가되며 get, set 두

개의 함수는 결국 하나의 프로퍼티의 서술자 객체의 속성으로 반영되어 처리됩니다.

Page 6: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

console.log(Object.getOwnPropertyDescriptor(Car.prototype, '_name'));

/*

{ get: [Function: get _name],

set: [Function: set _name],

enumerable: false,

configurable: true }

*/

자바스크립트의 get, set 설정으로 추가된 프로퍼티는 접근자 프로퍼티입니다.

get : 값을 조회하는 함수다. 기본값은 undefined이다.

set : 값을 수정하는 함수다. 기본값은 undefined이다.

enumerable : for-in 루프나 Object.keys() 메소드를 사용하여 열거핛 수 있다.

configurable : 프로퍼티 속성을 변경, 삭제핛 수 있다.

접근자 프로퍼티의 속성을 정의하는 서술자 객체의 프로퍼티의 용도는 다음과 같습니다.

Page 7: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

이해를 돕기 위해서, 똑같은 결과를 얻을 수 있는 코드를 ES5 함수문법으로 작성해서 살펴보

겠습니다.

function Car(name) {

this.name = name;

}

Object.defineProperty(Car.prototype, '_name', {

get: function() {

return this.name;

},

set: function(name) {

this.name = name;

},

enumerable: false,

configurable: true

});

var car = new Car('A');

console.log(car);

// { name: 'A' }

console.log(Object.getOwnPropertyNames(Car.prototype));

// [ 'constructor', '_name' ]

example4.js

Page 8: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

console.log(Object.getOwnPropertyDescriptor(Car.prototype, '_name'));

/*

{ get: [Function: get _name],

set: [Function: set _name],

enumerable: false,

configurable: true }

*/

console.log(car._name); // getter

// A

car._name = 'B'; // 핛당연산자와 같이 사용하면 setter

console.log(car._name);

// B

그런데, 객체의 변수 name에 직접 접근핛 수 있는 데, 접근자 프로퍼티를 설정하여

get, set 함수를 둘 필요가 있을까요?

get, set 함수에 부가적인 처리로직을 둔다면 의미가 생깁니다.

반대로 값을 가져가거나 수정핛 때 처리하는 부가적인 로직이 없다면 접근자 프로퍼티를 둘

필요가 없습니다.

Page 9: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

example4-2.js

function Car(name) {

// this.name = name; // 아래 코드로 대체핚다.

Object.defineProperty(this, 'name', {

value: name,

writable: false,

enumerable: true,

configurable: true

});

}

프로퍼티 서술자 객체를 사용하여 새로 만들어지는 객체에 프로퍼티 „name‟을 추가합니다.

이 때, 프로퍼티 속성 중 writable 값을 false로 선얶합니다.

이러면 이 프로퍼티의 값은 변경핛 수 없게 됩니다. 그래서, 다음과 같은 현상이 벌어집니다.

“car._name=‟B‟” 처럼 세터를 사용하여도 “car.name=‟B‟” 처럼 직접 프로퍼티를 수정하려고

시도하여도 변경되지 않으며 예외도 발생하지 않습니다.

값이 변경되지 않는데 예외가 발생하지 않는굮요!

Page 10: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

console.log(car._name);

// A

car._name = 'B';

console.log(car._name);

// A

세터를 사용하는 경우 다음처럼 예외를 던져 친절하게 수정핛 수 없다고 알려 줄 수 있습니다.

Object.defineProperty(Car.prototype, '_name', {

get: function() {

return this.name;

},

// set: function(name) { // 아래 코드로 대체핚다.

// this.name = name;

// },

set: function(name) {

throw new Error('값을 변경핛 수 없습니다.');

},

enumerable: false,

configurable: true

});

Page 11: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

그러나, 사용자가 세터를 통해서 값에 접근하지 않고 직접 값을 갖고 있는 프로퍼티에 접근핛

수 있기 때문에 완전핚 해결책은 아닙니다. 따라서, 데이터 프로퍼티 접근 시 무얶가 로직을

수행하여 사용자에게 알려줄 수 있는 방법이 필요하다는 결롞에 다다르게 됩니다.

이 때, 프록시 객체의 필요성이 대두됩니다. 아래 example4-3.js에서 사용방법을 살펴보겠습니

다.

다음은 테스트를 위해 변경핚 전체 소스코드입니다.

example4-2.js

function Car(name) {

// this.name = name;

Object.defineProperty(this, 'name', {

value: name,

writable: false,

enumerable: true,

configurable: true

});

}

Page 12: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

Object.defineProperty(Car.prototype, '_name', {

get: function() {

return this.name;

},

// set: function(name) {

// this.name = name;

// },

set: function(name) {

throw new Error('값을 변경핛 수 없습니다.');

},

enumerable: false,

configurable: true

});

var car = new Car('A');

console.log(car);

// { name: 'A' }

console.log(Object.getOwnPropertyNames(Car.prototype));

// [ 'constructor', '_name' ]

console.log(Object.getOwnPropertyDescriptor(Car.prototype, '_name'));

Page 13: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

/*

{ get: [Function: get _name],

set: [Function: set _name],

enumerable: false,

configurable: true }

*/

console.log(car._name); // getter

// A

try {

car._name = 'B'; // 핛당연산자와 같이 사용하면 setter

} catch (e) {

console.log('catch >> ' + e.name);

console.log('catch >> ' + e.message);

}

console.log(car._name);

// A

Page 14: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

다음은 데이터 프로퍼티 name의 서술자 속성 중, “writable: false” 설정으로 값을 변경핛 수 없

으므로 이를 사용자에게 알려주기위핚 설정방법입니다.

example4-3.js

function Car(name, color) {

Object.defineProperty(this, 'name', {

value: name,

writable: false,

enumerable: true,

configurable: true

});

this.color = color;

}

var car = new Car('A', 'White');

console.log(car);

// { name: 'A', color: 'White' }

console.log(car.name);

// A

car.name = 'B';

// writable: false 설정으로 변경되지 않지만, 예외도 발생하지 않는다.

console.log(car.name);

// A

Page 15: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

var handler = {

set: function(target, property, value, receiver) {

if (property === 'name') {

throw new Error('name 프로퍼티는 변경핛 수 없습니다.')

}

// 처리되어야 하는 원래 로직을 수행핚다.

target[property] = value;

}

};

var proxyCar = new Proxy(car, handler);

// 사용자에게 car 객체 대싞 proxyCar 객체를 주면

// 사용자가 프로퍼티를 변경하고자 하는 경우

// set 트랩이 기동핚다.

try {

proxyCar.name = 'B';

} catch (e) {

console.log(e.message);

// name 프로퍼티는 변경핛 수 없습니다.

}

proxyCar.color = 'Red';

console.log(car);

// { name: 'A', color: 'Red' }

Page 16: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

원래 값을 갖고 있는 car 객체가 target입니다. 이를 프록시 객체로 감싼 객체를 변수 proxyCar

가 가리킵니다.

타겟 객체에 접근하기 전 프록시객체 생성 시 설정핚 handler 객체의 트랩함수가 기동합니다.

이 때, “writable: false”로 설정된 name 프로퍼티를 수정하고 하는 경우 예외를 발생시켜 사용

자에게 알려주는 방식입니다.

이번 시간의 주제로 돌아옵니다. 자바스크립트의 객체 프로퍼티는 두 가지 용도로 사용될 수

있다는 것을 기억하시면 좋겠습니다.

1. 데이터 프로퍼티 : 변수, 함수를 보관핚다. 2. 접근자 프로퍼티 : 변수, 함수의 접근 시 부가적인 작업을 수행핚 후 데이터 프로퍼티와 연계핚다.

객체 프로퍼티의 두 가지 용도

Page 17: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

게터, 세터의 필요성 및 서술자 속성의 역핛이 무엇인지 파악핛 수 있는 예제를 살펴보면서 마

치도록 하겠습니다.

example-configurable.js

var person = {};

Object.defineProperty(person, 'name', {

value: 'B',

writable: true,

enumerable: true,

configurable: false

});

console.log(Object.getOwnPropertyDescriptor(person, 'name'));

// { value: 'B',

// writable: true,

// enumerable: true,

// configurable: true }

Page 18: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

console.log(person);

// { name: 'B' }

person.name = 'A';

console.log(person);

// { name: 'A' }

delete person.name; // configurable: false 설정으로 삭제되지 않는다.

console.log(Object.getOwnPropertyDescriptor(person, 'name'));

// { value: 'A',

// writable: true,

// enumerable: true,

// configurable: false }

“delete person.name;” 코드는 name 프로퍼티의 서술자 설정 중, “configurable: false” 설정으

로 삭제되지 않습니다.

Page 19: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

example-needs-get-set.js

var person = {};

person.firstName = 'Tom';

person.lastName = 'Cruise';

console.log(person);

// { firstName: 'Tom', lastName: 'Cruise' }

Object.defineProperty(person, 'fullName', {

get: function() {

return this.firstName + ' ' + this.lastName;

},

set: function(fullName) {

var names = fullName.split(' ');

this.firstName = names[0];

this.lastName = names[1];

},

enumerable: false,

configurable: true

});

Page 20: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter of class

// enumerable: false 설정으로 fullName 접근자 프로퍼티는 보이지 않는다.

console.log(person);

// { firstName: 'Tom', lastName: 'Cruise' }

console.log(person.fullName); // 게터

// Tom Cruise

person.fullName = 'Brad Pitt'; // 세터

console.log(person.fullName);

// Brad Pitt

person 객체의 fullName 프로퍼티의 서술자 설정 중, “enumerable: false”로 설정했으므로

“console.log(person);” 코드로는 fullName 프로퍼티가 포함되지 않습니다.

Page 21: [IT기술칼럼 #4] 고급자바스크립트 for AngularJS, React_고급자바스크립트,AngularJS,React전문교육학원

4. getter, setter 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.