※ 이 글은 예전 블로그에서 퍼온 글입니다. 가독성이 나쁘다면 예전 블로그에서 읽어주세요.
※ 이 글은 프론트엔드 개발자를 위한 자바스크립트 프로그래밍의 글을 참고한 것입니다.
자바스크립트에서 생성자 패러다임은 유용하기도 하지만 단점도 있습니다.
바로, 인스턴스마다 메서드가 생성된다는 것입니다.
ECMAScript에서 함수는 객체이므로 함수를 정의할 때마다 새로운 객체 인스턴스가 생성되는 것이나 마찬가지입니다.
논리적으로 생성자는 다음과 같습니다.
// 다음 두 함수는 논리적으로 동등함.
// 1.
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function () {
alert(this.name);
}
}
// 2.
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = new Function("alert(this.name)");
}
생성자를 2와 같은 형태로 생각하면 Person의 각 인스턴스가 Function의 인스턴스를 가지며, 이 인스턴스가 name프로퍼티를 표시한다는 점을 명확히 알 수 있습니다.
엄밀히 말해 함수를 이런 식으로 생성하면 스코프 체인과 식별자 해석이란 점에서는 다르지만 Function의 새 인스턴스를 만드는 방식은 똑같습니다.
따라서 함수 이름이 같더라도 인스턴스가 다르면 둘은 다른 함수인데 다음 코드를 보면 명확히 알 수 있습니다.
다음 코드를 보면 명확히 알 수 있습니다.
var person1 = new Person();
var person2 = new Person();
alert(person1.sayName == person2.sayName); // false
문제점은 다음과 같습니다.
1. 똑같은 일을 하는 Function 인스턴스 두 개가 따로 존재해야 한다는 것
2. this 객체를 응용하여 함수가 런타임에서야 비로소 객체에 묶이도록 할 수 있다는 점.
다음과 같이 함수 정의를 생성자 밖으로 내보내면 이런 제한을 우회할 수 있습니다.
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = sayName;
}
function sayName() {
alert(this.name);
}
sayName( ) 함수를 생성자 바깥에 생성함으로써 person1과 person2는 전역 스코프에 정의된 sayName( ) 함수를 공유합니다.
이렇게 하면 함수 중복 문제를 막을 수 있지만, 일부 객체에서만 쓰이는 함수를 전역에 놓음으로서 전역 스코프를 어지럽힌다는 단점이 있습니다.
(이 문제는 1. 정적 고유변수를 사용해 특권 메서드를 만들거나 2. 프로토타입 패턴으로 해결할 수 있습니다.
하지만, 위의 두 방식도 아래와 같은 문제점이 있습니다.
1. 정적 고유변수를 사용할 시, 각 인스턴스가 독립 변수를 지닐 수 없고 변수를 검색하는데 시간이 늘어날 수 있습니다.
2. 프로토타입 패턴을 사용할 경우 인스턴스의 값이 공유된다는 큰 문제점이 있습니다.)
+ 참고하면 좋은 글들
'Programming > Javascript' 카테고리의 다른 글
Babel의 뜻과 사용법 (0) | 2020.04.07 |
---|---|
Doom이 아니라 DOM! (문서 객체 모델, Document Object Model) (0) | 2020.04.02 |
BOM (Browser Object Model)에 대한 정리 (0) | 2020.04.02 |
자바스크립트 관점에서 정리한 클래스(Class)와 프로토타입(Prototype)에 대하여 (0) | 2020.04.02 |
Drag and Drop과 관련하여 (Mozilla 참고) (0) | 2020.04.02 |