상세 컨텐츠

본문 제목

자바스크립트 디자인패턴(1)

자바스크립트/자바스크립트 디자인패턴

by somiyuralove 2020. 1. 18. 19:47

본문

출처 : 자바스크립트 디자인 패턴 / 사이먼팀스 저, 류영선 옮김

 

아래는 위 출처의 책을 토대로 스터디한 내용을 정리하였습니다.


1. 자바스크립트 객체

- 자바스크립트는 객체지향 언어이지만, 대부분의 사람들은 객체지향 언어를 사용하고 있지 않음.
- 자바스크립트는 객체뿐만 아니라 원시 데이터(primitives)를 포함하는 혼합된 객체 모델을 사용하고 있음.
- 자바스크립트는 다섯가지 원시 데이터 타입이 있음
( Undefined, Null, Boolean, String, Number)

아래의 코드에서 자바스크립트 원시 데이터의 박싱과 언박싱 버전을 확인할 수 있음

var numberOne = new Number(1);
var numberTwo = 2;
typeof numberOne; // 객체반환
console.log(numberOne);
typeof numberTwo; // 숫자반환
console.log(numberTwo);
var numberThree = numberOne + numberTwo;
typeof numberThree; // 숫자반환
console.log(numberThree);

자바스크립트에서 객체의 생성은 비교적 간단함.

var objectOne={};
typeof objectOne; // 객체반환
console.log(objectOne)
var objectTwo = new Object();
typeof objectTwo; // 객체반환
console.log(objectTwo)

자바스크립트가 동적인 언어이기 때문에 객체의 속성을 추가하는 일도 아주 간단함. 
심지어 객체가 생성된 후에도 가능. 

var objectOne = { value: 7 };
console.log(objectOne);
var objectTwo = {};
objectTwo.value = 7;
console.log(objectTwo);

객체는 데이터와 함수를 모두 포함하고 있음.
객체에 함수를 추가하는 코드를 아래에서 살펴보자

var functionObject = {};
functionObject.doThings = function() {
console.log("hello world");
}
functionObject.doThings();

위의 코드는 객체를 생성하는 동시에 할당하고 있어 다소 혼란스럽기때문에, 객체를 생성하는 구문으로 아래와 같이 개선
var functionObject = {
doThings: function() {
console.log("hello world");
}
}
functionObject.doThings();

그리고 아래와 같이 객체에 데이터와 기능을 혼합하는 방식도 사용가능함
var functionObject = {
greeting: "hello world",
doThings: function() {
console.log(this.greeting);
}
}
functionObject.doThings();

여기서 주의해야할 것은 자바스크립트는 시샵이나 자바 언어와는 다르게 객체의 항목은 세미콜론이 아닌 콤마로 구분함
더불어 doThings 함수에서 greeting 변수를 가르키기 위해 this 변수를 사용한다는 점이다.

var functionObject = {
greeting: "hello world",
doThings: function() {
console.log(this.greeting);
this.doOtherThings();
},
doOtherThings: function() {
console.log(this.greeting.split("").reverse().join(""));
}
}
functionObject.doThings();

자바스크립트에서의 this 키워드는 C 언어와 다르게 동작함. this는 이름 사용하는 함수의 소유자에 바인딩되어 있음.
앞의 코드에서 this는 functionObject에 바인딩되어 있지만, 함수가 객체의 외부에서 선언된다면 전역 객체를 참조함.
이벤트 핸들러와 같은 특정 상황에서는 이벤트를 발생시키는 객체에 재바인딩됨.

따라서 다음 코드에서 this는 target의 값을 갖음. 자바스크립트에서 this의 사용은 가장 까다로운 작업중 하나임.
var target = document.getElementById("someId");
target.addEventListener("click", function() {
console.log(this);
}, false);

아래코드는 생성자를 정의하고 새로운 객체가 이 함수에서 생성될 수 있게 해줌.
반환값이 없는 생성자는 객체가 생성될 때 호출되는 함수. 실제로는 자바스크립트 생성자는 생성된 객체를 반환.
var ThinkDoor = function() {
    this.greeting = "hello world";
    this.doThings = function() {
        console.log(this.greeting);
        this.doOtherThings();
    };
    this.doOtherThings = function() {
        console.log(this.greeting.split("").reverse().join(""));
    };
}
var instance = new ThinkDoor();
instance.doThings();

심지어 아래코드와 같이 내부 함수의 일부로 생성자를 만들어 내부 속성을 할당할 수도 있음.
var ThingDoer = function(greeting) {
    this.greeting = greeting;
    this.doThings = function() {
        console.log(this.greeting);
    }
}
var instance = new ThingDoer("hello universe");
instance.doThings();

2. 프로토타입 구축
자바스크립트는 실제 클래스를 생성하는 방법을 제공하지 않음, 구조체를 사용해 객체를 생성하는 경우 크나큰 단점이 존재.
복수의 객체를 생성하는 데 많은 시간이 소요될 뿐 아니라 많은 메모리를 필요로 함.
동일한 방식으로 생성했어도 각각의 객체는 완전히 다른 객체임.
이는 함수를 정의하는 데 사용된 메모리가 인스턴스 간에 공유되지 않음을 의미함.
더 재미있는 것은, 인스턴스를 변경하지 않고도 각각 독립적인 클래스의 인스턴스를 다시 정의할 수 있음.

var Castle = function(name) {
this.name = name;
this.build = function() {
console.log(this.name);
};
}
var instance1 = new Castle("Winterfell");
var instance2 = new Castle("Harrenhall");
instance1.build = function() { console.log("Moat Cailin"); }
instance1.build();
instance2.build();

위와 같은 방식으로 단일 인스턴스의 함수나 이미 정의된 객체를 변경하는 방법은 몽키 패치로 알려져 있음.
이 방법이 좋은지 나쁜지는 상황에 따라 다르지만, 큰 혼란을 야기할 수 있으므로 일반적으로는 기존의 클래스를 
확장하는 것이 더 좋은 방법으로 여겨짐.

사실 적절한 클래스 시스템이 없기 때문에 자바스크립트에서는 상속의 개념이 없음.
프로토타입(prototype)만이 존재할 뿐임.
기본적인 수준에서 보면, 자바스크립트의 객체는 키와 값으로 이루어진 배열의 집합체일 뿐임.
객체의 각각의 속성이나 함수는 이 배열의 한 부분으로 정의됨.

var Westeros;
(function (Westeros) {
(funciton (Structures) {
var Castle = (funciton () {
function Castle(name) {
this.name = name;
}
Castle.prototype.Build = funciton() {
console.log("Castle built: " + this.name);
};
return Castle;
})();
Structures.Castle = Castle;
}) (Westeros.Structures || (Westeros.Structures = {}));
var Structures = Westeros.Structures;
}) (Westeros || (Westeros = {}));

두번째 클래스를 생성하는 코드를 찾아볼수 있다.

var Westeros;
(function (Westeros) {
(function (Structures) {
var Castle = (function () {
function Castle(name) {
this.name = name;
}
Castle.prototype.Build = function() {
console.log("Castle built: " + this.name);
};
return Castle;
})();
Structures.Castle = Castle;
    var Wall = (function () {
        function Wall() {
            console.log("Wall constructed");
        }
        return Wall;
    })();
    Structures.Wall = Wall;
}) (Westeros.Structures || (Westeros.Structures = {}));
var Structures = Westeros.Structures;
}) (Westeros || (Westeros = {}));

관련글 더보기

댓글 영역