This repository has been archived by the owner on Jul 24, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
classes-javascript.html
262 lines (234 loc) · 12 KB
/
classes-javascript.html
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
<!doctype html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta http-equiv="X-UA-Compatible" content="ie=edge"><meta name="description" content="Classes in Javascript allow a more object-oriented approach, creating instances with methods and properties."><!-- Bing --><meta name="msvalidate.01" content="45CBBE1BD8265A2217DFDA630EB8F84A" /><title>Tiny Brain Fans - Classes (Javascript)</title><link rel="stylesheet" href="tinystyle.css"></head><body>
<main id="main"><article id="content"><h1 id="title">Classes (Javascript)</h1><p>Classes in <a href="javascript.html">Javascript</a> generally are created with two different sections:</p>
<ol>
<li>The <code>prototypes</code> or <code>methods</code> will be how all the instances of the class should be <strong>similar</strong> (things like <code>addYear</code> for a person class). This is commonly done in the <code>prototype</code> object.</li>
<li>The constructor will define how the instances are <strong>different</strong> (the <code>name</code> property of a person class). This is commonly done through the invocation of the constructor, like <code>function (name) { this.name = name }</code>.</li>
</ol>
<h2>Class Types</h2>
<h3>Decorators</h3>
<p>A decorator is a function that accepts an object and <strong>adds more properties or functionality</strong> to it. It's common to use <strong>adjectives</strong> as the names of these decorators. Decorators allow for more DRY code and help keep all elements together that should be, allowing little ambiguity in execution.</p>
<pre><code class="language-javascript">// this decorator makes obj more 'carlike'
var carlike = function (obj, loc) {
obj.loc = loc;
obj.move = function () {
obj.loc++;
};
};
var newObj = {};
var newCar = carlike(newObj, 0);
</code></pre>
<h3>Functional Classes</h3>
<p>A functional class is a construct that is <strong>capable of making a fleet of objects</strong> that conform to the same interface. They are commonly capitalized in name. The functions that produce these functional classes are called <strong>constructors</strong>. The object that is returned is called an <strong>instance</strong> of that class. </p>
<p>The difference between a decorator and a functional class is that a decorator accepts their target object as input, whereas the class builds and returns the object it's augmenting.</p>
<pre><code class="language-javascript">var Car = function (loc) {
var obj = {loc: loc};
obj.move = function () {
obj.loc++;
}
return obj;
}
var newCar = Car(0);
</code></pre>
<h3>Functional Classes with Shared Methods</h3>
<p>Using shared methods allows you to save space in memory, as only one instance of a method needs to exist, as opposed to one for every single instance.</p>
<pre><code class="language-javascript">var Car = function (loc) {
var obj = {loc: loc};
// using UnderscoreJS (see polyfill)
return _.extend(obj, carMethods);
}
var carMethods = {
move: function () {
this.loc++;
}
}
var newCar = Car(0);
</code></pre>
<p><code>_.extend</code> polyfill:</p>
<pre><code class="language-javascript">var extend = function (destination, source) {
for (var key in source) {
destination[key] = source[key];
}
return destination;
}
</code></pre>
<h3>Prototypal Classes</h3>
<p>Using <code>Object.create()</code>, we can create an object that inherits all properties of the enclosed object into its <code>prototype</code>. This will mean that on a failed lookup, it will search within this object for a reference, inheriting the old objects as they were at the time of inheritance.</p>
<pre><code class="language-javascript">var Car = function (loc) {
var obj = Object.create(Car.prototype);
obj.loc = loc;
return obj;
}
Car.prototype.move = function () {
this.loc++;
};
var newCar = Car(0);
</code></pre>
<h3>Pseudoclassical Classes</h3>
<p>The pseudoclassical class is a <a href="javascript.html">Javascript</a> syntactic sugar that allows a more conventional style of object oriented programming to be implemented.</p>
<p>By running a function with the <code>new</code> keyword before it, the interpreter runs the program in a special "construction" mode. Since you will always want to be creating an object and returning it when you are finished, the <code>new</code> keyword adds these two lines at the beginning and end, respectively, to your function. The object created will be automatically bound to <code>this</code> and will use the <code>prototype</code> property found inside that function.</p>
<p>The two different parts of a pseudoclassical class are doing two distinct roles:</p>
<ol>
<li>the constructor is defining what is different about each instance. In this example, what <code>loc</code> is.</li>
<li>the methods are defining what is similar about each instance. In this example, what <code>move</code> does.</li>
</ol>
<pre><code class="language-javascript">var Car = function (loc) {
// var this = Object.create(Car.prototype);
this.loc = loc;
// copy all prototypes to `this`
// return this;
};
Car.prototype.move = function () {
this.loc++;
};
var newCar = new Car(0);
</code></pre>
<h3>ES6 Classes (<code>class</code>)</h3>
<p>The ES6 implementation is extremely similar to the pseudoclassical implementation, but uses more syntactic sugar to make it more readable and more similar to other object-oriented languages.</p>
<pre><code class="language-javascript">class Car {
constructor(loc) {
// var this = Object.create(Car.prototype);
this.loc = loc;
// copy all prototypes to `this`
// return this;
}
move() {
this.loc++;
}
}
var newCar = new Car(0);
</code></pre>
<h2>Polymorphism</h2>
<p>Polymorphism is the design of objects to be able to share behaviors and override certain shared behaviors to work more specifically on the new object. There is a super class and a sub class. The sub class inherits the properties and methods from the super class. In the following examples, the super is <code>Shape</code> and the sub is <code>Square</code> or <code>Triangle</code>. </p>
<h3>Functional Classes</h3>
<pre><code class="language-javascript">var Shape = function (name, sides, sideLength) {
var obj = {
name: name,
sides: sides,
sideLength: sideLength
};
var calcPerimeter = function () {
return obj.sides * obj.sideLength;
};
return obj;
};
var Square = function (name, sideLength) {
var obj = shape(name, 4, sideLength);
var calcArea = function () {
return Math.pow(obj.sideLength, 2);
};
return obj;
}
var newSquare = Square('square', 5);
</code></pre>
<h3>Functional with Shared Methods</h3>
<p>Using <code>_.extend</code> to update the object.</p>
<pre><code class="language-javascript">var Shape = function (name, sides, sideLength) {
var obj = {
name: name,
sides: sides,
sideLength: sideLength
};
// using UnderscoreJS (see polyfill)
return _.extend(obj, shapeMethods);
};
var shapeMethods = {
calcPerimeter: function () {
return this.sides * this.sideLength;
}
};
var Square = function (name, sideLength) {
var obj = Shape(name, 4, sideLength);
return _.extend(obj, squareMethods);
}
var squareMethods = {
calcArea: function () {
return Math.pow(this.sideLength, 2);
}
};
var newSquare = Square('square', 5);
</code></pre>
<h3>Prototypal Classes</h3>
<p>Using <code>Object.create()</code>.</p>
<pre><code class="language-javascript">var Shape = function (name, sides, sideLength) {
var obj = Object.create(Shape.prototype);
obj.name = name;
obj.sides = sides;
obj.sideLength = sideLength;
return obj;
};
Shape.prototype.calcPerimeter = function () {
return this.sides * this.sideLength;
};
var Square = function (name, sideLength) {
var obj = Object.create(Square.prototype);
obj.name = name;
obj.sides = 4;
obj.sideLength = sideLength;
return obj;
}
Square.prototype = Object.create(Shape.prototype);
Square.prototype.constructor = Square; // otherwise is `Shape`
Square.prototype.calcArea = function () {
return Math.pow(this.sideLength, 2);
};
var newSquare = Square('square', 5);
</code></pre>
<h3>Pseudoclassical Classes</h3>
<p>Using the <code>new</code> keyword.</p>
<pre><code class="language-javascript">var Shape = function (name, sides, sideLength) {
// this = Object.create(Shape.prototype);
this.name = name;
this.sides = sides;
this.sideLength = sideLength;
// return this;
};
Shape.prototype.calcPerimeter = function () {
return this.sides * this.sideLength;
};
var Square = function (name, sideLength) {
this.name = name;
this.sides = 4;
this.sideLength = sideLength;
};
Square.prototype = new Shape();
Square.prototype.constructor = Square; // otherwise is `Shape`
Square.prototype.calcArea = function () {
return Math.pow(this.sideLength, 2);
};
var newSquare = new Square('square', 5);
</code></pre>
<h3>ES6 Classes</h3>
<p>To create a class that inherits all the properties of another class, use <code>extends</code> after defining the <code>class</code> name.</p>
<pre><code class="language-javascript">class Shape {
constructor (name, sides, sideLength) {
this.name = name;
this.sides = sides;
this.sideLength = sideLength;
}
calcPerimeter () {
return this.sides * this.sideLength;
}
};
class Square extends Shape {
constructor (name, sideLength) {
super(name, 4, sideLength);
}
calcArea () {
return Math.pow(this.sideLength, 2);
}
}
var newSquare = new Square('square', 5);
</code></pre>
<h2>Property Lookup/Prototype Chains</h2>
<p>If you are looking for a given property of an object, the interpreter will first look at the object itself, and if it fails on that lookup, will look at any other objects that are associated via prototype chain.</p>
<p>To have an ongoing prototype chain, where one object will always default on a failed lookup to searching within another object, you can use <code>var newObj = Object.create(oldObj)</code>. <code>newObj</code> will now default to looking up any failed lookups in <code>oldObj</code>. The values will be calculated during the lookup time, as the values are not stored or copied into the new object. The new object has a link to the old object and will perform on a lookup on the old object in its current state.</p>
<h2>References</h2>
<ol start="2">
<li><a href="http://underscorejs.org/#extend" target="_blank">http://underscorejs.org/#extend</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create" target="_blank">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes" target="_blank">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Test_your_skills:_Object-oriented_JavaScript" target="_blank">https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Test_your_skills:_Object-oriented_JavaScript</a></li>
<li><a href="https://stackoverflow.com/questions/44391149/es6-classes-ability-to-perform-polymorphism" target="_blank">https://stackoverflow.com/questions/44391149/es6-classes-ability-to-perform-polymorphism</a></li>
<li><a href="https://radialglo.github.io/blog/2014/11/24/understanding-pseudoclassical-inheritance-in-javascript/" target="_blank">https://radialglo.github.io/blog/2014/11/24/understanding-pseudoclassical-inheritance-in-javascript/</a></li>
</ol>
<p class="last-modified">Last modified: 202206101419</p></article></main><footer><nav><a href="index.html">Sitemap</a></nav><div class="social"><p>Built using <a href="http://codeberg.org/milofultz/swiki" target="_blank" rel="noopener noreferrer">{{SWIKI}}</a></p><p><a href="http://codeberg.org/milofultz/" target="_blank" rel="noopener noreferrer">Codeberg</a></p><p><a href="http://milofultz.com/" target="_blank" rel="noopener noreferrer">milofultz.com</a></p><p><a href="https://merveilles.town/@milofultz" target="_blank" rel="me noopener noreferrer">Mastodon</a></p></div></footer></body></html>