모덴웹을 위한 Javascript, JQuery입문 [윤인성 지음] 참고
2017 - 10 - 31 (화)
캡슐화
- 자바스크립틔의 캡슐화(encapsulation) : 캡슐화 과정 사례
//캡슐화 전
function Rectangle(width, height){
this.width = width;
this.height = height;
}
Rectangle.prototype.getArea = function(){
return this.width * this.height;
}
var rectangle1 = new Rectangle(3,5) //
var rectangle2 = new Rectangle(-2,3) // rectangle2에 width 의 길이가 -2 가 들어갔다 논리상 불가하다.
console.log(rectangle1.getArea()) // 15가 출력
console.log(rectangle2.getArea()) // 출력은 -6으로 된다.
//캡슐화 후
function Rectangle(w,h){
var width = w;
var height = h;
this.getWidth = function (){ return this.width;}
this.getHeight = function(){return this.height;}
this.setWidth = function(w){ this.width = w;}
this.setHeight = function(h){ this.height =h;}
};
//이처럼 셋팅을 한다. //getter / setter 를 활용한다.
// 하지만 GETTER/SETTER 를 활용하는것이 캡슐화를 의미하는 것은아니다.
// 캡슐화는 만일의 상황을 대비해서 특정 속성 및 메서드를 사용자가 사용할 수 없게 숨겨둔 것이다.
상속
상속은 기존의 생성자 함수나 객체를 기반으로 새로운 생성자 함수나 객체를 쉽게만드는것 ,
기존 객체에서 속성과 메서드를 물려받는 것 의 의미이다.
(다른 프로그래밍 언어의 상속과 비슷한 것 같아 보인다.)
- 상속 예제
//정사각형 생성자
/*
function Square(length){
this.width = length;
this.height = length;
this.getWidth = function (){ return this.width;}
this.getHeight = function(){return this.height;}
this.setWidth = function(w){ this.width = w;}
this.setHeight = function(h){ this.height =h;}
}
Square.prototype.getArea = function(){
return this.getWidth()*this.getHeight();
}
var square1 = new Square(5);
console.log(square1.getArea()) // 25 출력
----------------------------------------------
*/
// 직사각형 생성자
function Rectangle(w,h){
var width = w;
var height = h;
this.getWidth = function (){ return width;}
this.getHeight = function(){return height;}
this.setWidth = function(w){ width = w;}
this.setHeight = function(h){ height =h;}
}
Rectangle.prototype.getArea = function(){
return this.getWidth() * this.getHeight();
}
var rectangle = new Rectangle(3,4);
console.log(rectangle.getArea())
console.log(rectangle.getWidth()); // 12출력
//위에 생성한 정사각형 생성자를 지우고 상속을 받을 수 있는 생성자 생성
function Square(length){
this.base = Rectangle; // Rectangle 생성자의 속성을 Square 에 추가하는 작업
this.base(length,length); //Rectangle 생성자의 속성 width, height 에 각각 length 값 대입
}
Square.prototype = Rectangle.prototype; // Square 의 프로토타입을 Rectangle을 가리키게한다.
Square.prototype.constructor = Square; // Square의 프로토타입 생성자는 Square 이다.
var square = new Square(5);
console.log(square.getArea()) //25 출력
- instanceof로 확인
var square = new Square(5);
alert(square instanceof Rectangle); //true 반환
클래스
- ECMAScript6 에서는 객체지향 언어를 두가지로 구분한다. : 클래스 기반 / 프로토타입 기반 객체지향언어
- 클래스 선언 vs 생성자 함수 선언
// 클래스 선언
class User{
constructor(id,pw){
this.id = id;
this.pw = pw;
}
}
const user = new User('shj','1234');
-----------------------------------
// 생성자 함수선언
function User(id,pw){
this.id = id;
this.pw = pw;
}
var user = new User('shj','1234');
//비교했을 때 큰 차이는 없다.
- 메서드 선언
class User{
constructor(id,pw,major){
this.id = id;
this.pw = pw;
this.major = major;
}
study(){
return this.major +"를 공부하고 있습니다."
}
}
const user = new User('shj','1234','Computer Science');
console.log(user.study());
- getter/setter
class User{
constructor(id,pw,major){
this._id = id; // 인스턴스 변수앞에 '_' 접두어가 붙었다.
this._pw = pw;
// 자바에서 private로 접근제어를 하는 것과 비슷한 의미로 쓰인다. 접근제어를 하는 것은 아니다.
this._major = major;
}
//getter/setter
get id(){return this._id;}
set id(id){this._id = id;}
get pw(){return this._pw;}
set pw(pw){this._pw = pw;}
get major(){return this._major;}
set major(major){this._major = major;}
}
const user = new User('shj','1234','Computer Science');
console.log(user.id); // 'shj' 출력
- class 에서의 상속
class Unit{
constructor(hp,power){
this._hp = hp;
this._power = power;
}
get hp(){return this._hp;}
set hp(hp){this._hp = hp;}
get power(){return this._power;}
set power(power){this._power = power;}
attack(){ return power+"파워로 공격";}
}
class Tank extends Unit{
constructor(){
super(100,50);
//console.log(this);
/* 출력값:
[object Object] {
_hp: 100,
_power: 50
}
*/
}
sizMod(){
if(this._power===50){
this._power +=30;}
else{
alert('이미 시즈모드 상태입니다');
}
}
tankStatus(){
if(this._power==50){
return "normal mode"
}else{
return "size mode"
}
}
sizModRemove(){
if(this._power===80){
super._power -=30;
}else{
alert('이미 시즈모드가 해제되었습니다.')
}
}
}
const tank1 = new Tank();
const tank2 = new Tank();
const tank3 = new Tank();
console.log(tank1.power);
tank1.sizMod(); //시즈모드 실행
console.log(tank1.power); //시즈모드 실행 후 공격력 30 증가
console.log(tank2.power); // 시즈모드 하지 않은 탱크는 공격력 50
tank3.sizModRemove(); // 이미 시즈모드가 해제되어있다는 alert