생성자 기능 대 공장 기능
누가 자바스크립트에서 생성자 함수와 공장 함수의 차이를 명확히 할 수 있습니까?
다른 것 대신에 어떤 것을 사용해야 합니까?
는 기적인생함다함사것음입다니는용다된께과와 함께 입니다.new
set 키워드가(JavaScript 로자새생함록개도성하를체으동j▁set,▁set함),록▁(▁keyword(ava도생키가성▁causes하whichthis
함수 내에서 해당 개체로 이동하고 개체를 반환합니다.):
var objFromConstructor = new ConstructorFunction();
공장 함수는 "일반" 함수와 같이 호출됩니다.
var objFromFactory = factoryFunction();
그러나 그것이 "공장"으로 간주되기 위해서는 어떤 객체의 새로운 인스턴스를 반환해야 할 것입니다. 만약 그것이 단지 부울 같은 것을 반환했다면 당신은 그것을 "공장" 함수라고 부르지 않을 것입니다.이는 다음과 같이 자동으로 발생하지 않습니다.new
하지만 어떤 경우에는 더 많은 유연성을 허용합니다.
매우 간단한 예에서 위에서 언급한 함수는 다음과 같이 보일 수 있습니다.
function ConstructorFunction() {
this.someProp1 = "1";
this.someProp2 = "2";
}
ConstructorFunction.prototype.someMethod = function() { /* whatever */ };
function factoryFunction() {
var obj = {
someProp1 : "1",
someProp2 : "2",
someMethod: function() { /* whatever */ }
};
// other code to manipulate obj in some way here
return obj;
}
물론 공장 기능을 단순한 예보다 훨씬 더 복잡하게 만들 수 있습니다.
출고 시 기능의 한 가지 장점은 반환할 개체가 일부 매개 변수에 따라 여러 유형일 수 있다는 것입니다.
생성자 사용의 이점
대부분의 책들은 당신에게 컨스트럭터를 사용하는 법을 가르칩니다.
new
this
.어떤 사람들은 그 방법을 좋아합니다.
var myFoo = new Foo();
단점
에 대한 내용은 됩니다.
new
모든 호출자가 생성자 구현과 밀접하게 연결되어 있습니다.공장의 추가 유연성이 필요한 경우 모든 발신자(규칙이 아닌 예외적인 경우 인정)를 리팩터링해야 합니다.ㅠㅠ
new
버그이므로 검사를 추가하는 을 강하게 . ( 이한일반버인생그올호확출바되인합는다니위검하기지플해고것야추해려강게하력러는을하가사를트이보레일러었르게적성자가이므로▁is,▁to▁a▁strongly▁shouldor▁is▁check▁addingplate▁such▁you▁a▁construct▁correctly다▁consider합▁called▁bug니▁boiler▁common▁ensure▁(▁that)if (!(this instanceof Foo)) { return new Foo() }
: 수 EDIT : ES6 (ES2015) 이후잊수없는을로▁)..new
class
생성자 또는 생성자가 오류를 던집니다.만약 당신이 한다면,
instanceof
확인, 그것은 여부에 대한 모호함을 남깁니다.new
필수 항목입니다.제 생각에는, 그러면 안 됩니다.당신은 효과적으로 전기 회로를 단락시켰습니다.new
요건. 즉, 결점 #1을 삭제할 수 있습니다.하지만 그 다음에는 이름을 제외한 모든 공장 기능이 있고, 추가적인 보일러 플레이트, 대문자, 그리고 덜 유연합니다.this
맥락.
생성자가 개방/폐쇄 원칙을 깨다
하지만 저의 주된 우려는 그것이 개방/폐쇄 원칙에 위배된다는 것입니다.생성자를 내보내기 시작하고, 사용자가 생성자를 사용하기 시작하면 공장의 유연성이 필요하다는 것을 알게 됩니다(예: 객체 풀을 사용하도록 구현을 전환하거나, 실행 컨텍스트 전체에서 인스턴스화하거나, 프로토타입 OOO를 사용하여 상속 유연성을 높이려면).
하지만 당신은 꼼짝 못합니다.생성자를 호출하는 모든 코드를 해제하지 않고는 변경할 수 없습니다.new
예를 들어 성능 향상을 위해 개체 풀 사용으로 전환할 수 없습니다.
또한, 생성자를 사용하는 것은 여러분에게 기만적인 것을 줍니다.instanceof
실행 컨텍스트 전체에서 작동하지 않으며, 생성자 프로토타입이 교체되면 작동하지 않습니다.또한 반환을 시작하는 경우에도 실패합니다.this
생성자에서 임의 개체 내보내기로 전환합니다. 생성자에서 공장과 같은 동작을 사용하려면 이 작업을 수행해야 합니다.
공장 사용의 이점
코드 감소 - 보일러 플레이트가 필요하지 않습니다.
임의 개체를 반환하고 임의 프로토타입을 사용할 수 있으므로 동일한 API를 구현하는 다양한 유형의 개체를 보다 유연하게 만들 수 있습니다.예를 들어 HTML5 및 플래시 플레이어의 인스턴스를 모두 만들 수 있는 미디어 플레이어 또는 DOM 이벤트 또는 웹 소켓 이벤트를 내보낼 수 있는 이벤트 라이브러리가 있습니다.또한 공장에서는 실행 컨텍스트 전반에서 개체를 인스턴스화하고, 개체 풀을 활용하며, 보다 유연한 프로토타입 상속 모델을 구현할 수 있습니다.
공장에서 건설업체로 전환할 필요가 없으므로 리팩터링은 문제가 되지 않습니다.
사용에 대한 없음.
new
하지 마. (그것은 만들 것입니다.this
나쁜 행동을 하다, 다음 점 참조).this
개체에 수 inside 일으로작동예는대에작이로로상개므를사동하체위다용여하있니수습반액내세할스부: 적하에예니다▁behaves있습▁(수스for세할▁the액▁as▁it▁object▁parent▁it▁would▁use).player.create()
,this
에대한을player
다른 방법으로 호출하는 것처럼 말입니다.call
그리고.apply
this
◦또한 매우 할 수 .프로토타입을 상위 개체에 저장하면 동적으로 기능을 전환하고 개체 인스턴스화에 매우 유연한 다형성을 사용할 수 있습니다.자본화 여부에 대한 모호성이 없습니다.하지 마.린트 공구는 불만을 표시한 다음 사용하려고 시도할 것입니다.
new
그러면 위에서 설명한 이점을 취소할 수 있습니다.어떤 사람들은 그 방법을 좋아합니다.
var myFoo = foo();
또는var myFoo = foo.create();
단점
new
예상대로 작동하지 않습니다(위 참조).해결책: 사용하지 마십시오.this
개체를 된 경우). foo.bar - (예: ()생가점 - 를로으표대호또법기경우출된괄호는법체instead표기개성자예▁doesn▁-). ◦: foo.bar 모듈 -this
에대한을foo
다른 모든 JavaScript 방법과 마찬가지로 -- 이점 참조).
생성자는 호출한 클래스의 인스턴스를 반환합니다.공장 기능은 무엇이든 반환할 수 있습니다.임의 값을 반환해야 하거나 클래스에 대규모 설정 프로세스가 있는 경우 공장 함수를 사용합니다.
생성자 함수 예제
function User(name) {
this.name = name;
this.isAdmin = false;
}
let user = new User("Jack");
new
▁on에 으로 된 객체를 만듭니다.User.prototype
및호라고 부릅니다.User
를 생된개사용으로this
value.value.value.new
피연산자에 대한 인수 식을 선택적으로 처리합니다.let user = new User;
원인이 될 것입니다
new
을 부르다User
논쟁의 여지 없이new
생성자가 객체 값을 반환하지 않는 한 생성자가 만든 객체를 반환합니다. 객체 값은 대신 반환됩니다.이것은 대부분 무시할 수 있는 에지 케이스입니다.
장단점
에 의해 합니다.prototype
true를 합니다.instanceOf
생성자 함수의 연산자입니다.
은 생성자의할 수 .prototype
생성자를 이미 사용한 후 속성입니다.생성자를 사용하여 생성자를 만든 경우에는 변경할 수 없습니다.class
키워드
는 성자기다사확수있장습다를 할 수 .extends
키워드
생자함수반수없을 반환할 수 없습니다.null
오류 값으로 지정합니다.형식이 에 개체데이형아로에무다에 의해 됩니다.new
.
출고 시 기능 예제
function User(name, age) {
return {
name,
age,
}
};
let user = User("Tom", 23);
를 기서공기다능제호출다니됩외고하음을여은장▁is▁without▁here▁called 없이 부릅니다.new
함수의 인수와 반환되는 개체의 유형이 있는 경우 함수는 직접 또는 간접 사용에 전적으로 책임이 있습니다.이 예에서는 인수에서 일부 속성이 설정된 단순 [Object Object]를 반환합니다.
장단점
호출자로부터 객체 생성의 구현 복잡성을 쉽게 숨깁니다.이 기능은 브라우저의 기본 코드 기능에 특히 유용합니다.
공장 기능이 항상 동일한 유형의 객체를 반환할 필요는 없으며 반환할 수도 있습니다.null
오류 표시기로 사용할 수 있습니다.
간단한 경우, 공장 기능은 구조와 의미가 단순할 수 있습니다.
반환된 개체는 일반적으로 공장 기능에서 상속되지 않습니다.prototype
및 산재, 그고반환false
instanceOf factoryFunction
.
수 .extends
함수에서 입니다.prototype
에서 대신 속성.prototype
공장 함수에 의해 사용되는 생성자의 속성.
공장은 "항상" 더 낫습니다.객체 지향 언어를 사용할 때
- 계약을 결정합니다(방법과 그들이 무엇을 할 것인지 결정합니다.
- 이러한 메소드를 노출하는 인터페이스를 만듭니다(자바스크립트에서는 인터페이스가 없으므로 구현을 확인하는 방법을 생각해내야 합니다).
- 필요한 각 인터페이스의 구현을 반환하는 팩토리를 만듭니다.
구현(새 개체로 생성된 실제 개체)은 공장 사용자/소비자에게 노출되지 않습니다.이는 공장 개발자가 계약을 파기하지 않는 한 새로운 구현을 확장하고 창출할 수 있다는 것을 의미합니다.또한 공장 소비자는 코드를 변경하지 않고도 새로운 API의 이점을 누릴 수 있습니다. 만약 새로운 구현을 사용하고 "새로운" 구현을 사용한다면 "새로운" 구현을 사용하기 위해 "새로운"을 사용하는 모든 라인을 변경해야 합니다.그들의 코드는 변하지 않아요
공장들 - 다른 무엇보다도 - 봄의 틀은 완전히 이 아이디어를 중심으로 지어집니다.
공장은 추상화 계층이며, 모든 추상화와 마찬가지로 복잡성에 비용이 듭니다.공장 기반 API를 접하면 특정 API에 대한 공장을 파악하는 것이 API 소비자에게 어려울 수 있습니다.생성자의 경우 검색 가능성은 사소한 것입니다.
cctors와 공장 간에 결정할 때 복잡성이 유익성에 의해 정당화되는지 여부를 결정해야 합니다.
Javascript 생성자는 이것 이외의 것을 반환하거나 정의되지 않은 것을 반환함으로써 임의의 공장이 될 수 있습니다.따라서 js에서는 검색 가능한 API와 객체 풀링/캐싱이라는 두 가지 장점을 모두 활용할 수 있습니다.
저는 공장 기능이 건설자 기능보다 우수하다고 생각합니다.용사를 합니다.
new
생성자 기능을 사용하여 우리는 객체를 생성하는 특정한 방법에 코드를 바인딩하는 반면 공장을 사용하면 자유로워지므로 우리 자신을 바인딩하지 않고 더 다양한 인스턴스를 생성할 수 있습니다.다음과 같은 클래스가 있다고 가정해 보겠습니다.const file = new CreateFile(이름)
CreateFile 클래스를 리팩터하여 서버에서 지원하는 파일 형식에 대한 하위 클래스를 생성하려면 다음과 같이 고급 팩토리 함수를 작성할 수 있습니다.
function CreateFile(name) {
if (name.match(/\.pdf$/)) {
return new FilePdf(name);
} else if (name.match(/\.txt$/)) {
return new FileTxt(name);
} else if (name.match(/\.md$/)) {
return new FileMd(name);
} else {
throw new Error("Not supprted file type");
}
}
기능을 수 . 사용자는 공장기능로, 는개구수있고, 로부터들다있니습라고 .
encapsulation
.function createPerson(name) { const privateInfo = {}; // we create person object const person = { setName(name) { if (!name) { throw new Error("A person must have a name"); } privateInfo.name = name; }, getName() { return privateInfo.name; }, }; person.setName(name); return person; }
차이점에 대해서는 에릭 엘리엇이 아주 잘 설명했습니다.
하지만 두 번째 질문에 대해서는:
다른 것 대신에 어떤 것을 사용해야 합니까?
만약 당신이 객체 지향적인 배경에서 온 것이라면, 생성자 함수는 당신에게 더 자연스럽게 보입니다.이런 식으로 사용하는 것을 잊어서는 안 됩니다.new
키워드
언급URL : https://stackoverflow.com/questions/8698726/constructor-function-vs-factory-functions
'programing' 카테고리의 다른 글
구성 맵 kubernetes 여러 환경 (0) | 2023.07.22 |
---|---|
SQLSTATE[42S22]:열을 찾을 수 없음: 1054 'where 절'의 'id' 알 수 없는 열(SQL: 'id'에서 * 선택 = 5 제한 1) (0) | 2023.07.22 |
Python: 지정된 날짜의 시작 및 끝 데이터 제공 (0) | 2023.07.22 |
왜 RabbitMQ 대신 셀러리를 사용합니까? (0) | 2023.07.22 |
Python 예약 단어 및 내장 목록을 라이브러리에서 사용할 수 있습니까? (0) | 2023.07.22 |