자바스크립트는 ES6에서 class 키워드가 추가되었다.
ES5 자바스크립트를 사용했을 때 사용자 입장에서 아쉬운 부분들에 대해 보완되어 나온 게 ES6라고 생각하면 된다.
class 키워드를 사용하여, 이전보다 간단하고 원활하게 객체의 재사용이 가능하다.
그렇다면 class 키워드의 추가가 있기 전까지 어떠한 방식으로 인스턴스를 만들었는 지에 대해 정리하고자 한다.
four Instantiation Patterns
- Functional
- Functional Shared
- Prototypal
- Pseudoclassical
1. Functional
// ES6 이전 변수 선언 시, var 키워드 사용
var Test = function() {
var someInstance = {};
someInstance.position = 0;
//메소드 함수 : 객체를 부모로 갖는 함수
someInstance.move = function() {
// 메소드 호출 시 this는 부모 객체
this.position += 1;
}
return someInstance;
}
var test1 = Test(); // {position: 0, move: ƒ}
var test2 = Test(); // {position: 0, move: ƒ}
test1.move()
console.log(test1) // {position: 1, move: ƒ}
class : Test / instance : test1, test2 / method : move
간단한 개념을 설명하고 가자면, 메소드 함수는 객체를 부모로 갖는 함수이며, 메소드 함수 내의 this는 부모 객체이다.
위코드에서 Test 함수를 호출 할 경우 기본 position의 값은 0으로 지정되어있다.
하지만, 메소드 함수 move를 호출할 경우엔?
Test 함수 내 someInstance.move 함수가 실행 된다.
메소드 함수를 호출할 경우 메소드 함수의 this는 someInstance 객체가 되어 someInstance.position이 증가하는 것과 같다.
// 초기 위치 지정 가능
var Test = function(position) {
var someInstance = {};
someInstance.position = position;
someInstance.move = function() {
this.position += 1;
}
return someInstance;
}
var test1 = Test(5); //
초기 값을 지정하고 싶다면 위와 같이 함수 내에서 인자를 전달 받아 저장하는 방법도 있다.
2. Functional Shared
// someInstance와 someMethods를 합치는 함수 (Test 함수 내 호출)
var extend = function(to, from) {
for (var key in from) {
to[key] = from[key];
}
}
// 메소드를 담아줄 객체
var someMethods = {};
someMethods.move = function() {
this.position += 1;
};
// class로 사용할 Test 함수
var Test = function(position) {
var someInstance = {
position: position,
};
extend(someInstance, someMethods);
return someInstance;
};
var test1 = Test(5); // {position: 5, move: ƒ}
var test2 = Test(10); // {position: 10, move: ƒ}
test1.move();
console.log(test1); // {position: 6, move: ƒ}
class : Test / instance : test1, test2 / method : move
Functional 방식으로 작성한 코드와 결과는 같으나 뭔가 복잡해보인다.
위의 코드는 Test 함수가 호출될 경우 전달 받은 position 인자를 someInstance.position의 값으로 할당하고 extend 함수가 호출되어 메소드함수가 담겨있는 객체를 순회하며 기존 someInstance 객체 내 position의 값이 변경되었다면 덮어 씌울 수 있도록 구현되었다.
고로, 메소드 함수 move가 호출될 경우에도 변경된 position의 값으로 덮어 씌워지는 것이다.
굳이 이러한 방식을 사용한 이유는 이전 functional 방식으로 인스턴스를 만들어낼 때, 모든 메소드를 someInstance에 할당하게 되어 각 인스턴들이 메소드의 수 만큼 메모리를 더 차지하는 부분을 보완했다고 볼 수 있다.
3. Prototypal
var someMethods = {};
someMethods.move = function() {
this.position += 1;
};
var Test = function(position) {
// Object.create는 특정 객체를 프로토타입으로 하는 객체를 생성해주는 함수
var someInstance = Object.create(someMethods);
someInstance.position = position;
return someInstance;
}
var test1 = Test(5); // {position: 5, move: ƒ}
var test2 = Test(10); // {position: 10, move: ƒ}
class : Test / instance : test1, test2 / method : move
이전 인스턴스 생성과정과 다른 점이 눈에 띌 것이다.
Object.create() 메소드는 특정 객체를 기본 프로토타입으로 갖는 객체를 생성해주는 함수이다.
해당 메소드를 통해 인스턴스를 만들어낼 수 있도록 구현했다.
4. Pseudoclassical
var Test = function(position) {
this.position = position;
};
Test.prototype.move = function() {
this.position += 1;
};
var test1 = new Test(5);
var test2 = new Test(10);
class : Test / instance : test1, test2 / method : move
메소드를 프로토타입으로 만든 뒤, 객체 생성을 원할 때에는 class 함수와 함께 new 연산자를 같이 작성해야 한다.
가장 유용하게 많이 쓰이는 방식이라고 하니 꼭 숙지하는 것이 좋을 것 같다.
** class 키워드를 사용한 인스턴스 생성 과정 ES6 추가
class Test {
constructor(position) {
this.position = position;
}
move() {
this.position += 1;
}
}
let test1 = new Test(5); // Test {position: 5}
let test2 = new Test(10); // Test {position: 10}
test1.move();
console.log(test1); // Test {position: 6}
class : Test / instance : test1, test2 / method : move
class 키워드를 사용하여 class 함수 생성이 가능하다. class 키워드에 사용되는 함수명은 첫글자를 대문자로 작성하며,
constructor는 인스턴스가 초기화 될 때 실행 될 생성자 함수이다.
메소드는 constructor 외부에 작성 가능하다.
'Code > JavaScript' 카테고리의 다른 글
번들러 파헤치기 1 - 모듈 시스템의 발전과 역사 (commonJS, AMD, UMD, ESM-esmodule) (1) | 2024.02.29 |
---|---|
자바스크립트 / this 바인딩의 5가지 패턴 정리 (메소드 호출, call, apply ...) (0) | 2020.11.01 |
OOP(Object Oriented Programming) (0) | 2020.10.28 |
JavaScript Rest 파라미터, Spread 연산자, arguments 정리 / 차이 (0) | 2020.10.17 |
JavaScript 호이스팅 (Hoisting), let 과 var를 통한 예제 (0) | 2020.10.16 |