-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathcreational-design-patterns.html
More file actions
334 lines (283 loc) · 74.4 KB
/
creational-design-patterns.html
File metadata and controls
334 lines (283 loc) · 74.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>JavsScript - Creational Design Patterns</title>
<meta name="generator" content="VuePress 1.8.2">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="description" content="Factory Functions, Factory with Composition, Module and Revealing Module Patterns, Prototype Pattern, Singleton Pattern, Abstract Factory Pattern">
<meta property="og:site_name" content="DevTut">
<meta property="og:title" content="JavsScript - Creational Design Patterns">
<meta property="og:description" content="Factory Functions, Factory with Composition, Module and Revealing Module Patterns, Prototype Pattern, Singleton Pattern, Abstract Factory Pattern">
<meta property="og:type" content="article">
<meta property="og:url" content="/javascript/creational-design-patterns.html">
<meta property="og:image" content="/logo.png">
<meta name="twitter:title" content="JavsScript - Creational Design Patterns">
<meta name="twitter:description" content="Factory Functions, Factory with Composition, Module and Revealing Module Patterns, Prototype Pattern, Singleton Pattern, Abstract Factory Pattern">
<meta name="twitter:url" content="/javascript/creational-design-patterns.html">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="/logo.png">
<meta name="theme-color" content="#ffffff">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="msapplication-TileImage" content="/mstile-150x150.png">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="google-site-verification" content="76_rKXgwMVIjd-axJC_1zPV9OS4mEjvtgjYOWVkAdnQ">
<link rel="preload" href="/assets/css/0.styles.60619e34.css" as="style"><link rel="preload" href="/assets/js/app.1779e102.js" as="script"><link rel="preload" href="/assets/js/3.2cfa8016.js" as="script"><link rel="preload" href="/assets/js/1724.14afa607.js" as="script">
<link rel="stylesheet" href="/assets/css/0.styles.60619e34.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">DevTut</span></a> <div class="links"><form id="search-form" role="search" class="algolia-search-wrapper search-box"><input id="algolia-search-input" class="search-query"></form> <nav class="nav-links can-hide"> <a href="https://github.com/devtut/generate" target="_blank" rel="noopener noreferrer" class="repo-link">
GitHub
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"> <a href="https://github.com/devtut/generate" target="_blank" rel="noopener noreferrer" class="repo-link">
GitHub
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav> <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>JavaScript</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/javascript/" aria-current="page" class="sidebar-link">Disclaimer</a></li><li><a href="/javascript/getting-started-with-javascript.html" class="sidebar-link">Getting started with JavaScript</a></li><li><a href="/javascript/javascript-variables.html" class="sidebar-link">JavaScript Variables</a></li><li><a href="/javascript/built-in-constants.html" class="sidebar-link">Built-in Constants</a></li><li><a href="/javascript/comments.html" class="sidebar-link">Comments</a></li><li><a href="/javascript/console.html" class="sidebar-link">Console</a></li><li><a href="/javascript/datatypes-in-javascript.html" class="sidebar-link">Datatypes in Javascript</a></li><li><a href="/javascript/strings.html" class="sidebar-link">Strings</a></li><li><a href="/javascript/date.html" class="sidebar-link">Date</a></li><li><a href="/javascript/date-comparison.html" class="sidebar-link">Date Comparison</a></li><li><a href="/javascript/comparison-operations.html" class="sidebar-link">Comparison Operations</a></li><li><a href="/javascript/conditions.html" class="sidebar-link">Conditions</a></li><li><a href="/javascript/arrays.html" class="sidebar-link">Arrays</a></li><li><a href="/javascript/objects.html" class="sidebar-link">Objects</a></li><li><a href="/javascript/arithmetic-math.html" class="sidebar-link">Arithmetic (Math)</a></li><li><a href="/javascript/bitwise-operators.html" class="sidebar-link">Bitwise operators</a></li><li><a href="/javascript/constructor-functions.html" class="sidebar-link">Constructor functions</a></li><li><a href="/javascript/declarations-and-assignments.html" class="sidebar-link">Declarations and Assignments</a></li><li><a href="/javascript/loops.html" class="sidebar-link">Loops</a></li><li><a href="/javascript/functions.html" class="sidebar-link">Functions</a></li><li><a href="/javascript/functional-javascript.html" class="sidebar-link">Functional JavaScript</a></li><li><a href="/javascript/prototypes-objects.html" class="sidebar-link">Prototypes, objects</a></li><li><a href="/javascript/classes.html" class="sidebar-link">Classes</a></li><li><a href="/javascript/namespacing.html" class="sidebar-link">Namespacing</a></li><li><a href="/javascript/context-this.html" class="sidebar-link">Context (this)</a></li><li><a href="/javascript/setters-and-getters.html" class="sidebar-link">Setters and Getters</a></li><li><a href="/javascript/events.html" class="sidebar-link">Events</a></li><li><a href="/javascript/inheritance.html" class="sidebar-link">Inheritance</a></li><li><a href="/javascript/method-chaining.html" class="sidebar-link">Method Chaining</a></li><li><a href="/javascript/callbacks.html" class="sidebar-link">Callbacks</a></li><li><a href="/javascript/intervals-and-timeouts.html" class="sidebar-link">Intervals and Timeouts</a></li><li><a href="/javascript/regular-expressions.html" class="sidebar-link">Regular expressions</a></li><li><a href="/javascript/cookies.html" class="sidebar-link">Cookies</a></li><li><a href="/javascript/web-storage.html" class="sidebar-link">Web Storage</a></li><li><a href="/javascript/data-attributes.html" class="sidebar-link">Data attributes</a></li><li><a href="/javascript/json.html" class="sidebar-link">JSON</a></li><li><a href="/javascript/ajax.html" class="sidebar-link">AJAX</a></li><li><a href="/javascript/enumerations.html" class="sidebar-link">Enumerations</a></li><li><a href="/javascript/map.html" class="sidebar-link">Map</a></li><li><a href="/javascript/timestamps.html" class="sidebar-link">Timestamps</a></li><li><a href="/javascript/unary-operators.html" class="sidebar-link">Unary Operators</a></li><li><a href="/javascript/generators.html" class="sidebar-link">Generators</a></li><li><a href="/javascript/promises.html" class="sidebar-link">Promises</a></li><li><a href="/javascript/set.html" class="sidebar-link">Set</a></li><li><a href="/javascript/modals-prompts.html" class="sidebar-link">Modals - Prompts</a></li><li><a href="/javascript/execcommand-and-contenteditable.html" class="sidebar-link">execCommand and contenteditable</a></li><li><a href="/javascript/history.html" class="sidebar-link">History</a></li><li><a href="/javascript/navigator-object.html" class="sidebar-link">Navigator Object</a></li><li><a href="/javascript/bom-browser-object-model.html" class="sidebar-link">BOM (Browser Object Model)</a></li><li><a href="/javascript/the-event-loop.html" class="sidebar-link">The Event Loop</a></li><li><a href="/javascript/strict-mode.html" class="sidebar-link">Strict mode</a></li><li><a href="/javascript/custom-elements.html" class="sidebar-link">Custom Elements</a></li><li><a href="/javascript/data-manipulation.html" class="sidebar-link">Data Manipulation</a></li><li><a href="/javascript/binary-data.html" class="sidebar-link">Binary Data</a></li><li><a href="/javascript/template-literals.html" class="sidebar-link">Template Literals</a></li><li><a href="/javascript/fetch.html" class="sidebar-link">Fetch</a></li><li><a href="/javascript/scope.html" class="sidebar-link">Scope</a></li><li><a href="/javascript/modules.html" class="sidebar-link">Modules</a></li><li><a href="/javascript/screen.html" class="sidebar-link">Screen</a></li><li><a href="/javascript/variable-coercion-conversion.html" class="sidebar-link">Variable coercion/conversion</a></li><li><a href="/javascript/destructuring-assignment.html" class="sidebar-link">Destructuring assignment</a></li><li><a href="/javascript/websockets.html" class="sidebar-link">WebSockets</a></li><li><a href="/javascript/arrow-functions.html" class="sidebar-link">Arrow Functions</a></li><li><a href="/javascript/workers.html" class="sidebar-link">Workers</a></li><li><a href="/javascript/requestanimationframe.html" class="sidebar-link">requestAnimationFrame</a></li><li><a href="/javascript/creational-design-patterns.html" aria-current="page" class="active sidebar-link">Creational Design Patterns</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/javascript/creational-design-patterns.html#factory-functions" class="sidebar-link">Factory Functions</a></li><li class="sidebar-sub-header"><a href="/javascript/creational-design-patterns.html#factory-with-composition" class="sidebar-link">Factory with Composition</a></li><li class="sidebar-sub-header"><a href="/javascript/creational-design-patterns.html#module-and-revealing-module-patterns" class="sidebar-link">Module and Revealing Module Patterns</a></li><li class="sidebar-sub-header"><a href="/javascript/creational-design-patterns.html#prototype-pattern" class="sidebar-link">Prototype Pattern</a></li><li class="sidebar-sub-header"><a href="/javascript/creational-design-patterns.html#singleton-pattern" class="sidebar-link">Singleton Pattern</a></li><li class="sidebar-sub-header"><a href="/javascript/creational-design-patterns.html#abstract-factory-pattern" class="sidebar-link">Abstract Factory Pattern</a></li></ul></li><li><a href="/javascript/detecting-browser.html" class="sidebar-link">Detecting browser</a></li><li><a href="/javascript/symbols.html" class="sidebar-link">Symbols</a></li><li><a href="/javascript/transpiling.html" class="sidebar-link">Transpiling</a></li><li><a href="/javascript/automatic-semicolon-insertion-asi.html" class="sidebar-link">Automatic Semicolon Insertion - ASI</a></li><li><a href="/javascript/localization.html" class="sidebar-link">Localization</a></li><li><a href="/javascript/geolocation.html" class="sidebar-link">Geolocation</a></li><li><a href="/javascript/indexeddb.html" class="sidebar-link">IndexedDB</a></li><li><a href="/javascript/modularization-techniques.html" class="sidebar-link">Modularization Techniques</a></li><li><a href="/javascript/proxy.html" class="sidebar-link">Proxy</a></li><li><a href="/javascript/postmessage-and-messageevent.html" class="sidebar-link">.postMessage() and MessageEvent</a></li><li><a href="/javascript/weakmap.html" class="sidebar-link">WeakMap</a></li><li><a href="/javascript/weakset.html" class="sidebar-link">WeakSet</a></li><li><a href="/javascript/escape-sequences.html" class="sidebar-link">Escape Sequences</a></li><li><a href="/javascript/behavioral-design-patterns.html" class="sidebar-link">Behavioral Design Patterns</a></li><li><a href="/javascript/server-sent-events.html" class="sidebar-link">Server-sent events</a></li><li><a href="/javascript/async-functions-async-await.html" class="sidebar-link">Async functions (async/await)</a></li><li><a href="/javascript/async-iterators.html" class="sidebar-link">Async Iterators</a></li><li><a href="/javascript/how-to-make-iterator-usable-inside-async-callback-function.html" class="sidebar-link">How to make iterator usable inside async callback function</a></li><li><a href="/javascript/tail-call-optimization.html" class="sidebar-link">Tail Call Optimization</a></li><li><a href="/javascript/bitwise-operators-real-world-examples-snippets.html" class="sidebar-link">Bitwise Operators - Real World Examples (snippets)</a></li><li><a href="/javascript/tilde.html" class="sidebar-link">Tilde ~</a></li><li><a href="/javascript/using-javascript-to-get-set-css-custom-variables.html" class="sidebar-link">Using javascript to get/set CSS custom variables</a></li><li><a href="/javascript/selection-api.html" class="sidebar-link">Selection API</a></li><li><a href="/javascript/file-api-blobs-and-filereaders.html" class="sidebar-link">File API, Blobs and FileReaders</a></li><li><a href="/javascript/notifications-api.html" class="sidebar-link">Notifications API</a></li><li><a href="/javascript/vibration-api.html" class="sidebar-link">Vibration API</a></li><li><a href="/javascript/battery-status-api.html" class="sidebar-link">Battery Status API</a></li><li><a href="/javascript/fluent-api.html" class="sidebar-link">Fluent API</a></li><li><a href="/javascript/web-cryptography-api.html" class="sidebar-link">Web Cryptography API</a></li><li><a href="/javascript/security-issues.html" class="sidebar-link">Security issues</a></li><li><a href="/javascript/same-origin-policy-cross-origin-communication.html" class="sidebar-link">Same Origin Policy & Cross-Origin Communication</a></li><li><a href="/javascript/error-handling.html" class="sidebar-link">Error Handling</a></li><li><a href="/javascript/global-error-handling-in-browsers.html" class="sidebar-link">Global error handling in browsers</a></li><li><a href="/javascript/debugging.html" class="sidebar-link">Debugging</a></li><li><a href="/javascript/unit-testing-javascript.html" class="sidebar-link">Unit Testing Javascript</a></li><li><a href="/javascript/evaluating-javascript.html" class="sidebar-link">Evaluating JavaScript</a></li><li><a href="/javascript/linters-ensuring-code-quality.html" class="sidebar-link">Linters - Ensuring code quality</a></li><li><a href="/javascript/anti-patterns.html" class="sidebar-link">Anti-patterns</a></li><li><a href="/javascript/performance-tips.html" class="sidebar-link">Performance Tips</a></li><li><a href="/javascript/memory-efficiency.html" class="sidebar-link">Memory efficiency</a></li><li><a href="/javascript/reserved-keywords.html" class="sidebar-link">Reserved Keywords</a></li><li><a href="/javascript/contributors.html" class="sidebar-link">The Contributors</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="creational-design-patterns"><a href="#creational-design-patterns" class="header-anchor">#</a> Creational Design Patterns</h1> <p>Design patterns are a good way to keep your <strong>code readable</strong> and DRY. DRY stands for <strong>don't repeat yourself</strong>. Below you could find more examples about the most important design patterns.</p> <h2 id="factory-functions"><a href="#factory-functions" class="header-anchor">#</a> Factory Functions</h2> <p>A factory function is simply a function that returns an object.</p> <p>Factory functions do not require the use of the <code>new</code> keyword, but can still be used to initialize an object, like a constructor.</p> <p>Often, factory functions are used as API wrappers, like in the cases of <a href="https://jquery.com" target="_blank" rel="noopener noreferrer">jQuery<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> and <a href="http://momentjs.com" target="_blank" rel="noopener noreferrer">moment.js<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>, so users do not need to use <code>new</code>.</p> <p>The following is the simplest form of factory function; taking arguments and using them to craft a new object with the object literal:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">cowFactory</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">{</span>
name<span class="token operator">:</span> name<span class="token punctuation">,</span>
<span class="token function-variable function">talk</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Moo, my name is '</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">var</span> daisy <span class="token operator">=</span> <span class="token function">cowFactory</span><span class="token punctuation">(</span><span class="token string">'Daisy'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// create a cow named Daisy</span>
daisy<span class="token punctuation">.</span><span class="token function">talk</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "Moo, my name is Daisy"</span>
</code></pre></div><p>It is easy to define private properties and methods in a factory, by including them outside of the returned object. This keeps your implementation details encapsulated, so you can only expose the public interface to your object.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">cowFactory</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">function</span> <span class="token function">formalName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> name <span class="token operator">+</span> <span class="token string">' the cow'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token punctuation">{</span>
<span class="token function-variable function">talk</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Moo, my name is '</span> <span class="token operator">+</span> <span class="token function">formalName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">var</span> daisy <span class="token operator">=</span> <span class="token function">cowFactory</span><span class="token punctuation">(</span><span class="token string">'Daisy'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
daisy<span class="token punctuation">.</span><span class="token function">talk</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "Moo, my name is Daisy the cow"</span>
daisy<span class="token punctuation">.</span><span class="token function">formalName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ERROR: daisy.formalName is not a function</span>
</code></pre></div><p>The last line will give an error because the function <code>formalName</code> is closed inside the <code>cowFactory</code> function. This is a <a href="http://stackoverflow.com/documentation/javascript/480/scope/1575/closures#t=20170117072939024722" target="_blank" rel="noopener noreferrer">closure<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>.</p> <p>Factories are also a great way of applying functional programming practices in JavaScript, because they are functions.</p> <h2 id="factory-with-composition"><a href="#factory-with-composition" class="header-anchor">#</a> Factory with Composition</h2> <p><a href="http://programmers.stackexchange.com/questions/134097/why-should-i-prefer-composition-over-inheritance" target="_blank" rel="noopener noreferrer"><strong>'Prefer composition over inheritance'</strong><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> is an important and popular programming principle, used to assign behaviors to objects, as opposed to inheriting many often unneeded behaviors.</p> <p><strong>Behaviour factories</strong></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> <span class="token function-variable function">speaker</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">state</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">var</span> noise <span class="token operator">=</span> state<span class="token punctuation">.</span>noise <span class="token operator">||</span> <span class="token string">'grunt'</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token punctuation">{</span>
<span class="token function-variable function">speak</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>state<span class="token punctuation">.</span>name <span class="token operator">+</span> <span class="token string">' says '</span> <span class="token operator">+</span> noise<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> <span class="token function-variable function">mover</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">state</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">{</span>
<span class="token function-variable function">moveSlowly</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>state<span class="token punctuation">.</span>name <span class="token operator">+</span> <span class="token string">' is moving slowly'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token function-variable function">moveQuickly</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>state<span class="token punctuation">.</span>name <span class="token operator">+</span> <span class="token string">' is moving quickly'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p><strong>Object factories</strong></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> <span class="token function-variable function">person</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> age</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">var</span> state <span class="token operator">=</span> <span class="token punctuation">{</span>
name<span class="token operator">:</span> name<span class="token punctuation">,</span>
age<span class="token operator">:</span> age<span class="token punctuation">,</span>
noise<span class="token operator">:</span> <span class="token string">'Hello'</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span> <span class="token comment">// Merge our 'behaviour' objects</span>
<span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token function">speaker</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token function">mover</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> <span class="token function-variable function">rabbit</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> colour</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">var</span> state <span class="token operator">=</span> <span class="token punctuation">{</span>
name<span class="token operator">:</span> name<span class="token punctuation">,</span>
colour<span class="token operator">:</span> colour
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span>
<span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token function">mover</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p><strong>Usage</strong></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> fred <span class="token operator">=</span> <span class="token function">person</span><span class="token punctuation">(</span><span class="token string">'Fred'</span><span class="token punctuation">,</span> <span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
fred<span class="token punctuation">.</span><span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// outputs: Fred says Hello</span>
fred<span class="token punctuation">.</span><span class="token function">moveSlowly</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// outputs: Fred is moving slowly</span>
<span class="token keyword">var</span> snowy <span class="token operator">=</span> <span class="token function">rabbit</span><span class="token punctuation">(</span><span class="token string">'Snowy'</span><span class="token punctuation">,</span> <span class="token string">'white'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
snowy<span class="token punctuation">.</span><span class="token function">moveSlowly</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// outputs: Snowy is moving slowly</span>
snowy<span class="token punctuation">.</span><span class="token function">moveQuickly</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// outputs: Snowy is moving quickly</span>
snowy<span class="token punctuation">.</span><span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ERROR: snowy.speak is not a function</span>
</code></pre></div><h2 id="module-and-revealing-module-patterns"><a href="#module-and-revealing-module-patterns" class="header-anchor">#</a> Module and Revealing Module Patterns</h2> <h3 id="module-pattern"><a href="#module-pattern" class="header-anchor">#</a> Module Pattern</h3> <p>The Module pattern is a <a href="https://en.wikipedia.org/wiki/Module_pattern#Module_as_a_design_pattern" target="_blank" rel="noopener noreferrer">creational and structural design pattern<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> which provides a way of encapsulating private members while producing a public API. This is accomplished by creating an <a href="http://stackoverflow.com/documentation/javascript/186/functions/843/immediately-invoked-function-expressions" target="_blank" rel="noopener noreferrer">IIFE<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> which allows us to define variables only available in its scope (through <a href="http://stackoverflow.com/documentation/javascript/480/scope/1575/closures#t=201608151305143230866" target="_blank" rel="noopener noreferrer">closure<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>) while returning an object which contains the public API.</p> <p>This gives us a clean solution for hiding the main logic and only exposing an interface we wish other parts of our application to use.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> Module <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token comment">/* pass initialization data if necessary */</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// Private data is stored within the closure</span>
<span class="token keyword">var</span> privateData <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token comment">// Because the function is immediately invoked,</span>
<span class="token comment">// the return value becomes the public API</span>
<span class="token keyword">var</span> api <span class="token operator">=</span> <span class="token punctuation">{</span>
<span class="token function-variable function">getPrivateData</span><span class="token operator">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> privateData<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token function-variable function">getDoublePrivateData</span><span class="token operator">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> api<span class="token punctuation">.</span><span class="token function">getPrivateData</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> api<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token comment">/* pass initialization data if necessary */</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="revealing-module-pattern"><a href="#revealing-module-pattern" class="header-anchor">#</a> Revealing Module Pattern</h3> <p>The Revealing Module pattern is a variant in the Module pattern. The key differences are that all members (private and public) are defined within the closure, the return value is an object literal containing no function definitions, and all references to member data are done through direct references rather than through the returned object.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> Module <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token comment">/* pass initialization data if necessary */</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// Private data is stored just like before</span>
<span class="token keyword">var</span> privateData <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token comment">// All functions must be declared outside of the returned object</span>
<span class="token keyword">var</span> <span class="token function-variable function">getPrivateData</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> privateData<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> <span class="token function-variable function">getDoublePrivateData</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// Refer directly to enclosed members rather than through the returned object</span>
<span class="token keyword">return</span> <span class="token function">getPrivateData</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// Return an object literal with no function definitions</span>
<span class="token keyword">return</span> <span class="token punctuation">{</span>
getPrivateData<span class="token operator">:</span> getPrivateData<span class="token punctuation">,</span>
getDoublePrivateData<span class="token operator">:</span> getDoublePrivateData
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token comment">/* pass initialization data if necessary */</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="revealing-prototype-pattern"><a href="#revealing-prototype-pattern" class="header-anchor">#</a> Revealing Prototype Pattern</h3> <p>This variation of the revealing pattern is used to separate the constructor to the methods. This pattern allow us to use the javascript language like a objected oriented language:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">//Namespace setting</span>
<span class="token keyword">var</span> NavigationNs <span class="token operator">=</span> NavigationNs <span class="token operator">||</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// This is used as a class constructor </span>
NavigationNs<span class="token punctuation">.</span><span class="token function-variable function">active</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">current<span class="token punctuation">,</span> length</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>current <span class="token operator">=</span> current<span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>length <span class="token operator">=</span> length<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// The prototype is used to separate the construct and the methods </span>
NavigationNs<span class="token punctuation">.</span>active<span class="token punctuation">.</span><span class="token function-variable function">prototype</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// It is a example of a public method because is revealed in the return statement</span>
<span class="token keyword">var</span> <span class="token function-variable function">setCurrent</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">//Here the variables current and length are used as private class properties </span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> <span class="token keyword">this</span><span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">$</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>current<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">addClass</span><span class="token punctuation">(</span><span class="token string">'active'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token punctuation">{</span> setCurrent<span class="token operator">:</span> setCurrent <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Example of parameterless constructor </span>
NavigationNs<span class="token punctuation">.</span><span class="token function-variable function">pagination</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
NavigationNs<span class="token punctuation">.</span>pagination<span class="token punctuation">.</span><span class="token function-variable function">prototype</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// It is a example of a private method because is not revealed in the return statement</span>
<span class="token keyword">var</span> <span class="token function-variable function">reload</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// do something</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token comment">// It the only public method, because it the only function referenced in the return statement</span>
<span class="token function-variable function">getPage</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">link</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span>link<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> options <span class="token operator">=</span> <span class="token punctuation">{</span>url<span class="token operator">:</span> a<span class="token punctuation">.</span><span class="token function">attr</span><span class="token punctuation">(</span><span class="token string">'href'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> type<span class="token operator">:</span> <span class="token string">'get'</span><span class="token punctuation">}</span>
$<span class="token punctuation">.</span><span class="token function">ajax</span><span class="token punctuation">(</span>options<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">done</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// after the the ajax call is done, it calls private method</span>
<span class="token function">reload</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token punctuation">{</span>getPage <span class="token operator">:</span> getPage<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>This code above should be in a separated file .js to be referenced in any page that is needed. It can be used like this:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> menuActive <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">NavigationNs<span class="token punctuation">.</span>active</span><span class="token punctuation">(</span><span class="token string">'ul.sidebar-menu li'</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
menuActive<span class="token punctuation">.</span><span class="token function">setCurrent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="prototype-pattern"><a href="#prototype-pattern" class="header-anchor">#</a> Prototype Pattern</h2> <p>The prototype pattern focuses on creating an object that can be used as a blueprint for other objects through prototypal inheritance. This pattern is inherently easy to work with in JavaScript because of the native support for prototypal inheritance in JS which means we don't need to spend time or effort imitating this topology.</p> <p><strong>Creating methods on the prototype</strong></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">Welcome</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token class-name">Welcome</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">sayHello</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token string">'Hello, '</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">+</span> <span class="token string">'!'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">var</span> welcome <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Welcome</span><span class="token punctuation">(</span><span class="token string">'John'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
welcome<span class="token punctuation">.</span><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// => Hello, John!</span>
</code></pre></div><p><strong>Prototypal Inheritance</strong></p> <p>Inheriting from a 'parent object' is relatively easy via the following pattern</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token class-name">ChildObject</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token class-name">ParentObject</span><span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token class-name">ChildObject</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>constructor <span class="token operator">=</span> ChildObject<span class="token punctuation">;</span>
</code></pre></div><p>Where <code>ParentObject</code> is the object you wish to inherit the prototyped functions from, and <code>ChildObject</code> is the new Object you wish to put them on.</p> <p>If the parent object has values it initializes in it's constructor you need to call the parents constructor when initializing the child.</p> <p>You do that using the following pattern in the <code>ChildObject</code> constructor.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">ChildObject</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">ParentObject</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>A complete example where the above is implemented</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">RoomService</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> order</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// this.name will be set and made available on the scope of this function</span>
<span class="token function">Welcome</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>order <span class="token operator">=</span> order<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// Inherit 'sayHello()' methods from 'Welcome' prototype</span>
<span class="token class-name">RoomService</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token class-name">Welcome</span><span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// By default prototype object has 'constructor' property. </span>
<span class="token comment">// But as we created new object without this property - we have to set it manually,</span>
<span class="token comment">// otherwise 'constructor' property will point to 'Welcome' class</span>
<span class="token class-name">RoomService</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>constructor <span class="token operator">=</span> RoomService<span class="token punctuation">;</span>
<span class="token class-name">RoomService</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">announceDelivery</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token string">'Your '</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>order <span class="token operator">+</span> <span class="token string">' has arrived!'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token class-name">RoomService</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">deliverOrder</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">' '</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">announceDelivery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">var</span> delivery <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">RoomService</span><span class="token punctuation">(</span><span class="token string">'John'</span><span class="token punctuation">,</span> <span class="token string">'pizza'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
delivery<span class="token punctuation">.</span><span class="token function">sayHello</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// => Hello, John!,</span>
delivery<span class="token punctuation">.</span><span class="token function">announceDelivery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Your pizza has arrived!</span>
delivery<span class="token punctuation">.</span><span class="token function">deliverOrder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// => Hello, John! Your pizza has arrived!</span>
</code></pre></div><h2 id="singleton-pattern"><a href="#singleton-pattern" class="header-anchor">#</a> Singleton Pattern</h2> <p>The Singleton pattern is a design pattern that restricts the instantiation of a class to one object. After the first object is created, it will return the reference to the same one whenever called for an object.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> Singleton <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// instance stores a reference to the Singleton</span>
<span class="token keyword">var</span> instance<span class="token punctuation">;</span>
<span class="token keyword">function</span> <span class="token function">createInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// private variables and methods</span>
<span class="token keyword">var</span> _privateVariable <span class="token operator">=</span> <span class="token string">'I am a private variable'</span><span class="token punctuation">;</span>
<span class="token keyword">function</span> <span class="token function">_privateMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'I am a private method'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token punctuation">{</span>
<span class="token comment">// public methods and variables</span>
<span class="token function-variable function">publicMethod</span><span class="token operator">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'I am a public method'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
publicVariable<span class="token operator">:</span> <span class="token string">'I am a public variable'</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token punctuation">{</span>
<span class="token comment">// Get the Singleton instance if it exists</span>
<span class="token comment">// or create one if doesn't</span>
<span class="token function-variable function">getInstance</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>instance<span class="token punctuation">)</span> <span class="token punctuation">{</span>
instance <span class="token operator">=</span> <span class="token function">createInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> instance<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p><strong>Usage:</strong></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// there is no existing instance of Singleton, so it will create one</span>
<span class="token keyword">var</span> instance1 <span class="token operator">=</span> Singleton<span class="token punctuation">.</span><span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// there is an instance of Singleton, so it will return the reference to this one</span>
<span class="token keyword">var</span> instance2 <span class="token operator">=</span> Singleton<span class="token punctuation">.</span><span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>instance1 <span class="token operator">===</span> instance2<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</code></pre></div><h2 id="abstract-factory-pattern"><a href="#abstract-factory-pattern" class="header-anchor">#</a> Abstract Factory Pattern</h2> <p>The Abstract Factory Pattern is a creational design pattern that can be used to define specific instances or classes without having to specify the exact object that is being created.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">Car</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"Car"</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>wheels <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token function">Truck</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"Truck"</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>wheels <span class="token operator">=</span> <span class="token number">6</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token function">Bike</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"Bike"</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>wheels <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token keyword">const</span> vehicleFactory <span class="token operator">=</span> <span class="token punctuation">{</span>
<span class="token function-variable function">createVehicle</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">type</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">switch</span> <span class="token punctuation">(</span>type<span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">case</span> <span class="token string">"car"</span><span class="token operator">:</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Car</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">case</span> <span class="token string">"truck"</span><span class="token operator">:</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Truck</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">case</span> <span class="token string">"bike"</span><span class="token operator">:</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Bike</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">default</span><span class="token operator">:</span>
<span class="token keyword">return</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> car <span class="token operator">=</span> vehicleFactory<span class="token punctuation">.</span><span class="token function">createVehicle</span><span class="token punctuation">(</span><span class="token string">"Car"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Car { name: "Car", wheels: 4 } </span>
<span class="token keyword">const</span> truck <span class="token operator">=</span> vehicleFactory<span class="token punctuation">.</span><span class="token function">createVehicle</span><span class="token punctuation">(</span><span class="token string">"Truck"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Truck { name: "Truck", wheels: 6 } </span>
<span class="token keyword">const</span> bike <span class="token operator">=</span> vehicleFactory<span class="token punctuation">.</span><span class="token function">createVehicle</span><span class="token punctuation">(</span><span class="token string">"Bike"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Bike { name: "Bike", wheels: 2 } </span>
<span class="token keyword">const</span> unknown <span class="token operator">=</span> vehicleFactory<span class="token punctuation">.</span><span class="token function">createVehicle</span><span class="token punctuation">(</span><span class="token string">"Boat"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// null ( Vehicle not known )</span>
</code></pre></div><h4 id="remarks"><a href="#remarks" class="header-anchor">#</a> Remarks</h4> <p>In software engineering, a software design pattern is a general reusable solution to a commonly occurring problem within a given context in software design.</p></div> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/devtut/generate/edit/master/docs/javascript/creational-design-patterns.md" target="_blank" rel="noopener noreferrer">Edit this page on GitHub</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
←
<a href="/javascript/requestanimationframe.html" class="prev">
requestAnimationFrame
</a></span> <span class="next"><a href="/javascript/detecting-browser.html">
Detecting browser
</a>
→
</span></p></div> </main></div><div class="global-ui"><!----></div></div>
<script src="/assets/js/app.1779e102.js" defer></script><script src="/assets/js/3.2cfa8016.js" defer></script><script src="/assets/js/1724.14afa607.js" defer></script>
</body>
</html>