-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclassesInJS.js
275 lines (238 loc) · 7 KB
/
classesInJS.js
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
/*Class like in EcmaScript 5*/
function Person(name) {
this.name = name;
}
Person.prototype.getName = function() {
console.log(this.name);
};
var person = new Person("Brendan Eich");
person.getName(); // outputs "Brendan Eich"
console.log(person instanceof Person); // true
console.log(person instanceof Object); // true
/*Class basics*/
class Person{
constructor(name){//Special function else all are concise functions
this.name = name;//Best place to declare Own Properties
}
getName(){
alert(this.name);
}
}
let person = new Person("Brendan Eich");
person.getName(); // outputs "Brendan Eich"
console.log(person instanceof Person); // true
console.log(person instanceof Object); // true
console.log(typeof Person); // function
console.log(typeof Person.prototype.getName); // function- but yes with a class the .prototype is a read-only thing
/*So what's the difference between the function way and the class way?*/
let PersonType2 = (function() {
"use strict";
const PersonType2 = function(name) { // So that PersonType2 could'nt be assigned to other object by mistake
// make sure the function was called with new
if (typeof new.target === "undefined") {
throw new Error("Constructor must be called with new.");
}
this.name = name;
}
Object.defineProperty(PersonType2.prototype, "getName", {
value: function() {
// make sure the method wasn't called with new
if (typeof new.target !== "undefined") {
throw new Error("Method cannot be called with new.");
}
console.log(this.name);
},
enumerable: false, // Will not be visible in a for in loop
writable: true, // Writable
configurable: true // Can be deleted via delete getName
});
return PersonType2;
}()); // Hoisting is like the let
/*class in expression*/
var aClass = class{
constructor(name){
this.name = name;
}
getName(){
console.log(this.name);
}
}
let aVar = new aClass('test');
aVar.getName();
/*Singleton uses*/
let Person = new class{
constructor(name){
this.name = name;
}
getName(){
console.log(this.name);
}
}('troy')
Person.getName();
/*Generators in Class*/
class Collection {
constructor() {
this.items = [];
}
*[Symbol.iterator]() {
yield *this.items;
}
}
var collection = new Collection();
collection.items.push(1);
collection.items.push(2);
collection.items.push(3);
for (let x of collection) {
console.log(x);
}
// Output:
// 1
// 2
// 3
/*Old Static Way*/
function Person(name) {
this.name = name;
}
// static method
Person.create = function(name) {
return new PersonType(name);
};
// instance method
Person.prototype.sayName = function() {
console.log(this.name);
};
var person = Person.create("hector");
/*Using ES6 static keyword*/
class Person {
// equivalent of the Person constructor
constructor(name) {
this.name = name;
}
// equivalent of Person.prototype.sayName
sayName() {
console.log(this.name);
}
// equivalent of PersonType.create
static create(name) {
return new PersonClass(name);
}
}
let person = PersonClass.create("Igememnon"); // static members accessbale only via class name not instance and
//
/*Old way of Inheritance*/
function Rectangle(length, width) {
this.length = length;
this.width = width;
}
Rectangle.prototype.getArea = function() {
return this.length * this.width;
};
function Square(length) {
Rectangle.call(this, length, length);
}
Square.prototype = Object.create(new Rectangle());//
var square = new Square(3);
console.log(square.getArea()); // 9
console.log(square instanceof Square); // true
console.log(square instanceof Rectangle); // true
/*ES 6 inheritance*/
class Rectangle {
constructor(length, width) {
this.length = length;
this.width = width;
}
getArea() {
return this.length * this.width;
}
}
class Square extends Rectangle {
constructor(length) {
// equivalent of Rectangle.call(this, length, length)
// this is error before super
super(length, length);
}
}
var square = new Square(3);
console.log(square.getArea()); // 9
console.log(square instanceof Square); // true
console.log(square instanceof Rectangle); // true
/*Multiple Inheritance*/
let SerializableMixin = {
serialize() {
return JSON.stringify(this);
}
};
let AreaMixin = {
getArea() {
return this.length * this.width;
}
};
function mixin(...mixins) {
var base = function() {};
Object.assign(base.prototype, ...mixins);//merge the objects
return base;
}
class Square extends mixin(AreaMixin, SerializableMixin) {
constructor(length) {
super();
this.length = length;
this.width = length;
}
}
var x = new Square(3);
console.log(x.getArea()); // 9
console.log(x.serialize()); // "{"length":3,"width":3}"
/*Inheriting Built in Objects*/
class PrinceArray extends Array {
}
var colors = new PrinceArray();
colors[0] = "Prisales";
console.log(colors.length); //
/*Derived Class can choose wat to return- self or parent*/
class MyClass {
static get [Symbol.species]() {
return this;
}
constructor(value) {
this.value = value;
}
clone() {
return new this.constructor[Symbol.species](this.value);
}
}
class MyDerivedClass1 extends MyClass {
// empty
}
class MyDerivedClass2 extends MyClass {
static get [Symbol.species]() {
return MyClass;
}
}
let instance1 = new MyDerivedClass1("paan"),
clone1 = instance1.clone(),
instance2 = new MyDerivedClass2("singh"),
clone2 = instance2.clone();
console.log(clone1 instanceof MyClass); // true
console.log(clone1 instanceof MyDerivedClass1); // true
console.log(clone2 instanceof MyClass); // true
console.log(clone2 instanceof MyDerivedClass2); // false
// Encapsulation, Inheritance, Abstraction, Multiple inheritance
/*Abstraction*/
// abstract base class
class Shape {
constructor() {
if (new.target === Shape) {
throw new Error("This class cannot be instantiated directly.")
}
}
}
class Rectangle extends Shape {
constructor(length, width) {
super();
this.length = length;
this.width = width;
}
}
var x = new Shape(); // throws an error
var y = new Rectangle(3, 4); // no error
console.log(y instanceof Shape); // true