Před ES6, bylo tam hodně zmatek ohledně rozdíly mezi tovární funkce a funkce konstruktoru JavaScript. Vzhledem k tomu, že ES6 má klíčové slovo „třída“, zdá se, že mnoho lidí si myslí, že vyřešilo mnoho problémů s funkcemi konstruktoru. Pojďme prozkoumat hlavní rozdíly, o kterých si stále musíte být vědomi.,
za Prvé, pojďme se podívat na příklady každého z nich:
Každá z těchto strategií prodejny metod na společný prototyp, a volitelně podporuje soukromá data pomocí funkce konstruktoru uzávěry. Jinými slovy, mají většinou stejné vlastnosti a mohou být většinou používány zaměnitelně.
v JavaScriptu může každá funkce vrátit nový objekt. Když to není funkce konstruktoru nebo třída, nazývá se to tovární funkce.,
ES6 tříd desugar na konstruktor funkce, takže vše, co následuje o konstruktor funkce platí také pro ES6 tříd:
class Foo {}console.log(typeof Foo); // function
Konstruktory síly volající použít new
klíčové slovo. Továrny ne, to je ono, ale to má některé relevantní vedlejší účinky.
takže co dělá Klíčové slovonew
?,
Poznámka: Budeme používat
instance
odkazovat na nově vytvořenou instanci aConstructor
odkázat na konstruktor funkce nebo třídy, které vytvořil instanci.
- vytvoří instanci novou instanci objektu a váže
this
v konstruktoru. - váže
instance.__proto__
naConstructor.prototype
. - jako vedlejší účinek 2 se váže
instance.__proto__.constructor
naConstructor
., - implicitně vrací
this
, což odkazuje nainstance
.
Výhody Konstruktérů & `class`
- Většina knihy vás naučí používat konstruktory třídy nebo.
-
this
odkazuje na nový objekt. - někteří lidé mají rádi způsob čtení
myFoo = new Foo()
. - může být mikro-optimalizace výkonu výhody, ale neměli byste se bát, že pokud máte profilované váš kód a prokázáno, že to je problém pro vás.,
Nevýhody Konstruktérů & `class`
Před ES6, zapomínání new
byla velmi častá chyba. Zvrátit to, mnoho lidí používá často používaný prosadit to:
function Foo() {
if (!(this instanceof Foo)) { return new Foo(); }
}
V ES6+ (ES2015) pokud se pokusíte volání konstruktoru třídy bez new
, to bude vždy házet chybu. Není možné vyhnout se vynucení požadavku new
na volající bez zabalení vaší třídy do tovární funkce.,
podrobnosti o instanci se dostanou do volajícího API (prostřednictvím „nového“ požadavku).
všechny volající jsou pevně spojeny s implementací konstruktoru. Pokud někdy potřebujete další flexibilitu továrny, refaktor je zlomová změna. Třída factory refactors jsou dost běžné, že se objeví v semenné Refactoring knihu, „Refactoring: Improving the Design of Existing Code“ Martin Fowler a Kent Beck, John Brant, William Opdyke, a Roberts.,
Konstruktory break Open / Closed Princip
, Protože new
požadavek, konstruktor funkce porušovat open/closed princip: API by měla být otevřená pro rozšíření, ale uzavřené pro změny.
tvrdí, že třídy, do továrny refaktorovat je dost běžné, že to by mělo být považováno za standardní rozšíření pro všechny konstruktory: přechod z třídy do továrny nesmí rozbít věci, ale v Javascriptu, to dělá.,
Pokud začnete vyvážející konstruktoru či třídy a uživatelé začít používat konstruktor, pak dolů na silnici, budete si uvědomit, budete potřebovat flexibilitu továrny, (například přepnout provádění použít objekt bazény, nebo k instanci po provedení kontextech, nebo mít více dědictví flexibilitu pomocí alternativní prototypy), můžete to snadno udělat tak, aniž by nutit refaktorovat na volající.,
Bohužel, v Javascriptu, přepínání z konstruktoru či třídy factory je lámání změna:
V příkladu výše, můžeme začít s třídou, ale chceme přidat schopnost nabídnout různé druhy auto svazky. K tomu továrna používá alternativní prototypy pro různé svazky automobilů. Použil jsem tuto techniku k ukládání různých implementací rozhraní přehrávače médií, výběr správného prototypu na základě typu média, které přehrávač potřeboval ovládat.,
Použití Konstruktory Umožňuje Klamné `instanceof`
Jeden z lámání změny v konstruktoru tovární refaktorovat je instanceof
. Někdy jsou lidé v pokušení použít instanceof
jako typ check guard ve svém kódu. To může být velmi problematické. Doporučuji, abyste se vyhnuli instanceof
.
`instanceof` leží.,
instanceof
nedělá kontrola typu tak, že budete očekávat, že podobné kontroly v silně typované jazyky. Místo toho provede kontrolu identity porovnáním objektu __proto__
s vlastností Constructor.prototype
.
nebude fungovat v různých paměťových sférách, jako jsou například iframes (běžný zdroj chyb v JavaScriptu 3rd party). To také nefunguje, pokud vaše Constructor.prototype
dostane nahrazen.,
To bude také nezdaří, pokud začnete s třídou nebo konstruktoru (který se vrací this
, souvisí s Constructor.prototype
), a pak přejít na export libovolný objekt (nejsou spojeny do Constructor.prototype
), což je to, co se stane, když změníte z konstruktoru do továrny.
stručně řečeno, instanceof
je dalším způsobem, jakým je přechod z konstruktoru na továrnu zlomovou změnou.
Výhody použití třídy
- pohodlná, samostatná syntaxe.,
- jediný, kanonický způsob, jak emulovat třídy v JavaScriptu. Před ES6 bylo v populárních knihovnách několik konkurenčních implementací.
- známější lidem z jazykového prostředí založeného na třídě.
Nevýhody Pomocí třídy
Všechny konstruktoru nevýhody, a navíc:
- Pokušení pro uživatelům vytvářet problematické třídy hierarchie pomocí
extends
klíčové slovo.,
Třídy hierarchie vést k spoustu známých problémů, v objektově orientovaném designu, včetně křehké základní třídy problém, gorila banán problém, duplikace nutně problém, a tak dále. Bohužel, třída poskytuje rozšiřuje jako koule dovolit házení a židle dovolit sedět. Pro více informací si přečtěte „dva pilíře JavaScriptu: Prototypal OO“a“ Inside the Dev Team Death Spiral“.,
stojí za zmínku, že konstruktéři i továrny mohou být také použity k vytvoření problematických hierarchií dědičnosti, ale pomocí klíčového slova „rozšiřuje“ třída vytváří cenovou nabídku, která vás vede špatnou cestou. Jinými slovy, povzbuzuje vás, abyste přemýšleli o nepružných (a často špatných) vztazích, spíše než o flexibilnějších kompozičních vztazích.
affordance je funkce, která poskytuje příležitost provést určitou akci., Například, knoflík poskytuje kroucení, páka umožňuje vytažení, tlačítko poskytuje lisování, atd…
Výhody Používání Továrny
Závody jsou mnohem více flexibilní než jeden konstruktor, funkce nebo třídy, a nemají vést lidi na scestí tím, lákavé je s `sahá` klíčové slovo a hluboké dědické hierarchie. Existuje mnoho bezpečnějších mechanismů opětovného použití kódu, které byste měli upřednostňovat před dědičností třídy, včetně funkcí a modulů.,
Vrátit libovolný objekt a použít libovolný prototyp
například, můžete snadno vytvářet různé typy objektů, které implementují stejné rozhraní API, např. multimediální přehrávač, který může vytvořit instanci hráči pro více typů video obsahu, které používají jiné rozhraní Api, pod kapotou, nebo událost knihovna, která může vyzařovat DOM události nebo web socket události.
Továrny můžete také vytvořit instanci objektů po spuštění kontexty, využít objekt bazény, a umožnit flexibilnější prototypal dědictví modely.,
no refactoring worries
nikdy byste neměli potřebu převést z továrny na Konstruktor, takže refactoring nikdy nebude problém.
No ‚ new ‚
žádná nejednoznačnost ohledně použití new
. Don ‚t. (to bude dělat this
chovat špatně, viz další bod).
Standardní „tohle“ chování
this
chová, jako by to normálně, takže jej můžete použít pro přístup k nadřazeného objektu. Například uvnitř player.create()
, this
odkazuje na hráče, stejně jako každá jiná metoda vyvolání by., call()
a apply()
také přiřadit this
podle očekávání.
Někteří lidé, jako způsob, jak `myFoo = createFoo()` čte
- není-li vytvořit odkaz z instance
Factory.prototype
— ale to je vlastně dobrá věc, protože nebudete mít klamnýinstanceof
. Místo tohoinstanceof
vždy selže. Viz výhody. -
this
se nevztahuje na nový objekt uvnitř továrny. Viz výhody., - může provádět pomaleji než funkce konstruktoru v mikro-optimalizačních benchmarcích. Pomalá cesta je stále velmi rychlá-miliony ops / s na starém počítači. To je pravděpodobnější, že se jedná o problém v knihovně nebo rámcovém kódu než v aplikačním kódu. Vždy benchmark z pohledu uživatele před použitím mikro-optimalizace.
Závěr
podle mého názoru class
může mít pohodlný syntaxe, ale to nemůže vynahradit skutečnost, že to láká neopatrné uživatelů k havárii na skalách třídy dědictví., Je to také riskantní, protože v budoucnu budete chtít upgrade na továrně, ale všechny vaše volající budou pevně vázané na funkci konstruktoru, protože new
klíčové slovo a skutečnost, že stěhování z třídy do továren je lámání změnit.
možná Si myslíte, že můžete jen refaktorovat volání stránky, ale na velké týmy, nebo v případě, že třída pracujete s je součástí veřejného API, můžete zlomit kód, který není ve vaší kontrolou. Jinými slovy, nemůžete vždy předpokládat, že refaktoring volajících je dokonce možnost.,
super věc o továrny je to, že nejsou jen silnější a více flexibilní, jsou to také nejjednodušší způsob, jak povzbudit celé týmy, a celé API uživatelské základny, použít vzory, které jsou jednoduché, flexibilní a bezpečný.