JavaScript 개체 생성 : 패턴 및 모범 사례 - Lee-hyuna/33-js-concepts-kr GitHub Wiki
이 기사에서는 다양한 스타일의 JavaScript 객체 생성을 살펴보고 각 객체가 점차적으로 다른 단계에서 어떻게 빌드 되는지 살펴 보겠습니다.
JavaScript는 객체 생성을 위한 다양한 스타일을 가지고 있으며,
신입이나 배테랑들도 마찬가지로 그들이 어떤 것을 사용해야 하는지에 대해 압도적으로 확신할 수 없다.
하지만 각각의 구문이 다양하고 얼마나 다르게 보일지 모르지만, 그것들은 여러분이 아마 알고 있는 것보다 더 유사하다.
객체 리터럴
둘러보기 첫번째는 JavaScript 객체 생성의 가장 간단한 방법입니다.
객체 리터럴 JavaScript는 그 객체를 "ex nilo"로 만들 수 있습니다 - 클래스 없음, 템플릿 없음, 프로토 타입 없음 - 그냥 poof!,
메소드와 데이터가 있는 객체 :
var o = {
x: 42,
y: 3.14,
f: function() {},
g: function() {}
};
하지만 단점이 있습니다. 다른 장소에서 같은 유형의 객체를 생성해야 한다면 객체의 메소드, 데이터 및 초기화를 복사하여 붙여 넣습니다.
하나의 객체가 아니라 객체의 집합을 만드는 방법이 필요합니다.
Factory Functions
JavaScript 객체 생성 둘러보기의 다음 단계는 팩토리 기능입니다.
이것은 동일한 구조, 인터페이스 및 구현을 공유하는 객체 패밀리를 만드는 가장 간단한 방법입니다.
대신 객체 리터럴을 직접 생성하는 대신 함수에서 객체 리터럴을 반환합니다.
이런 식으로 같은 유형의 객체를 여러 번 또는 여러 곳에 작성해야하는 경우 함수를 호출하기 만 하면됩니다.
function thing() {
return {
x: 42,
y: 3.14,
f: function() {},
g: function() {}
};
}
var o = thing();
하지만 단점이 있습니다. 이 JavaScript 객체 생성 방식은 메모리 팽창을 일으킬 수 있습니다.
각 객체에는 각 함수의 고유 한 복사본이 포함되어 있기 때문입니다. 이상적으로 모든 객체가 함수의 복사본을 하나만 공유하기를 원합니다.
프로토타입 체인
JavaScript는 프로토타입 체인이라고 하는 객체간에 데이터를 공유하는 기본 제공 메커니즘을 제공합니다.
객체의 속성에 접근하게 되면 다른 객체에 위임하여 해당 요청을 수행 할 수 있습니다.
우리는 그것을 사용하고 factory 함수를 변경하여 생성 된 각 객체가 해당 객체에 고유 한 데이터 만 포함하고 다른 모든 속성 요청을 단일 공유 객체에 위임 할 수 있습니다.
var thingPrototype = {
f: function() {},
g: function() {}
};
function thing() {
var o = Object.create(thingPrototype);
o.x = 42;
o.y = 3.14;
return o;
}
var o = thing();
실제로 이것은 언어가 기본으로 지원하는 일반적인 패턴입니다. 우리는 우리 자신의 공유 객체 (프로토 타입 객체)를 생성 할 필요가 없다.
대신 프로토 타입 객체가 모든 함수와 함께 자동으로 생성되며 여기에 공유 데이터를 넣을 수 있습니다.
thing.prototype.f = function() {};
thing.prototype.g = function() {};
function thing() {
var o = Object.create(thing.prototype);
o.x = 42;
o.y = 3.14;
return o;
}
var o = thing();
하지만 단점이 있습니다. 이것은 몇 차례 반복 될 것입니다.
thing 함수의 첫 번째 줄과 마지막 줄은 프로토타입 factory-to-factory factory 함수에서 거의 그대로 반복됩니다.
ES5 Classes
반복되는 선을 자체 기능으로 이동하여 격리 할 수 있습니다.
이 함수는 다른 임의의 함수의 프로토타입에 위임 한 객체를 만든 다음 새로 만든 객체를 인수로 사용하여 해당 함수를 호출하고 마지막으로 객체를 반환합니다.
function create(fn) {
var o = Object.create(fn.prototype);
fn.call(o);
return o;
}
// ...
Thing.prototype.f = function() {};
Thing.prototype.g = function() {};
function Thing() {
this.x = 42;
this.y = 3.14;
}
var o = create(Thing);
사실, 이것 역시 언어에 내재되어 있는 일반적인 패턴입니다.
우리가 정의한 create 함수는 실제로 new 키워드의 초보적인 버전이며 create를 new로 대체 할 수 있습니다.
Thing.prototype.f = function() {};
Thing.prototype.g = function() {};
function Thing() {
this.x = 42;
this.y = 3.14;
}
var o = new Thing();
이제 우리는 일반적으로 "ES5 클래스"라고 부르는 것에 도달했습니다.
그것들은 프로토타입 객체에 공유 데이터를 위임하고 반복적인 논리를 처리하기 위해 새 키워드에 의존하는 객체 작성 기능입니다.
하지만 단점이 있습니다. 그것은 길고 추악하며, 상속 구현은 더욱 장황하고 추합니다.
ES6 Classes
비교적 최근에 JavaScript에 추가 된 ES6 클래스는 동일한 작업을 수행하는 데 훨씬 명확한 구문을 제공합니다.
class Thing {
constructor() {
this.x = 42;
this.y = 3.14;
}
f() {}
g() {}
}
const o = new Thing();
비교
수년 동안 우리는 JavaScripter가 프로토타입 체인과 관련하여 on-and-off 관계를 유지해 왔으며 현재 가장 일반적으로 사용되는
두 가지 스타일은 프로토 타입 체인에 크게 의존하는 클래스 구문과 팩토리 함수입니다.
구문은 프로토 타입 체인에 전혀 의존하지 않습니다. 두 가지 스타일은 성능 및 기능면에서 약간 차이가 있습니다.
성능
JavaScript 엔진은 너무 많이 최적화되어 오늘날 우리 코드를보고 무엇이 더 빠를 것인지에 대해 판단하는 것은 거의 불가능합니다.
측정이 중요합니다. 그러나 때로는 측정도 우리를 실패시킬 수 있습니다. 일반적으로 업데이트 된 JavaScript 엔진은 6 주마다 출시되며 성능이 크게 변경 될 수 있으며 이전에 수행 한 측정 및 이러한 측정을 기반으로 한 모든 결정이 창 밖으로 나옵니다.
그래서, 나의 엄지 손가락의 규칙은 그것이 가장 정밀하고 가장 유익한 시간이 될 것이라는 가정하에 가장 공식적이고 가장 널리 사용되는 구문을 선호하는 것이 었습니다. 지금은 이것이 클래스 구문입니다. 이 글을 쓰면서 클래스 구문은 리터럴을 반환하는 팩토리 함수보다 약 3 배 빠릅니다.
특징
ES6에서 클래스와 팩토리 함수간에 몇 가지 기능상의 차이점이있었습니다.
오늘날 팩토리 함수와 클래스는 모두 약한 맵이있는 클로저와 클래스가 포함 된 진정한 개인 데이터 팩토리 함수를 시행 할 수 있습니다.
둘 다 다른 속성을 자체 객체에 혼합하여 클래스가 다중 상속 팩토리 함수를 구현할 수 있으며 클래스도
다른 프로토타입을 프로토타입 또는 클래스 팩토리 또는 프록시로 혼합하여 클래스를 상속 할 수 있습니다.
팩토리 함수와 클래스는 필요한 경우 임의의 객체를 반환 할 수 있습니다. 둘 다 간단한 구문을 제공합니다.
결론
모든 것을 고려하면 JavaScript 객체 생성에 대한 선호는 클래스 구문을 사용하는 것입니다.
표준 적이며 간단하고 깨끗하며 빠르며 한 번에 공장에서만 제공 할 수있는 모든 기능을 제공합니다.