-
Notifications
You must be signed in to change notification settings - Fork 0
/
revisit.js
323 lines (247 loc) · 6.95 KB
/
revisit.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
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
// dont use var
let letScopeA = "letGloablScopeA";
var varScopeB = "varGloablScopeB";
const constScopeC = "constGloablScopeC";
if (true) {
let letScopeA = "letBlockScopeA";
var varScopeB = "varBlockScopeB";
const constScopeC = "constBloclScopeC";
}
console.log(letScopeA);
console.log(varScopeB);
console.log(constScopeC);
// ----------
// this
const onePiece = {
joyBoy: "M.D.Luffy",
fifthG: function () {
console.log("'this' will points to:\n", this);
},
};
onePiece.fifthG();
// if
// const opObj = onePiece.fifthG;
// opObj() //point to windows object
// solution
const opObj1 = onePiece.fifthG.bind(onePiece);
opObj1();
// ------
// closure
function toyFactory(shape) {
const closureFun = function (color) {
return `the ${shape} toy with ${color} color `;
};
return closureFun;
}
const createCircleToy = toyFactory("circle");
const blueCircleToy = createCircleToy("blue");
console.log(blueCircleToy);
const createSquareToy = toyFactory("square");
const yellowCircleToy = createSquareToy("yellow");
console.log(yellowCircleToy);
// ----
// example2
function createCounter() {
let count = 0;
let prev = 0;
function incrementBy(value) {
prev = count;
count += value;
console.log(`Increment by ${value} {count: ${count}, prev: ${prev}}`);
}
function decrementBy(value) {
prev = count;
count -= value;
console.log(`Decrement by ${value} {count: ${count}, prev: ${prev}}`);
}
return {
incrementBy,
decrementBy,
};
}
// Example usage
const counter = createCounter();
counter.incrementBy(2); // {count: 2, prev: 0}
counter.incrementBy(2); // {count: 4, prev: 2}
counter.decrementBy(1); // {count: 3, prev: 4}
counter.incrementBy(3); // {count: 6, prev: 3}
counter.decrementBy(1); // {count: 5, prev: 6}
// ----
// 1: let create an empty object
let obj = Object.create(null);
console.log(obj);
// [Object: null prototype] {}
// we can add property with "defineProperty" params object, props, and descriptor
Object.defineProperty(obj, "key", {
value: "Monkey D luffy",
writable: false,
enumerable: true,
configurable: false,
});
console.log("using Object.create:", obj);
// using Object.create: [Object: null prototype] { key: 'Monkey D luffy' }
obj.key = "test";
console.log(obj);
// this wont reassign because we set the property writable to false
console.log(Object.keys(obj));
console.log(Object.values(obj));
// we can log because of the property enumerable set to true
/**
When configurable is set to true,
the property can be modified, deleted,
and its attributes can be changed using Object.defineProperty.
If configurable is set to false, the property becomes non-configurable,
and subsequent attempts to modify or delete the property will throw an error.
By default, properties created through normal object assignment
(without using defineProperty) are configurable.
Once a property becomes non-configurable, its configurability cannot be changed.
The configurable property only affects the property itself
and not its value or attributes.
*/
try {
// Trying to redefine the property
Object.defineProperty(obj, "key", {
value: "Luffy",
writable: true,
enumerable: true,
configurable: true, // This will throw an error since configurable is set to false
});
} catch (error) {
console.error("\x1b[31m%s\x1b[0m", error.message);
}
// Trying to delete the property
const deleteResult = delete obj.key;
if (!deleteResult) {
console.error("\x1b[31m%s\x1b[0m", "Cannot delete the 'key' property", deleteResult);
}
// using getter and setter in object
// older method
const person = {};
Object.defineProperty(person, 'name', {
get: function() {
return this._name;
},
set: function(value) {
this._name = value;
},
enumerable: true,
configurable: true
});
person.name = 'Monkey D. Garp';
console.log(person.name); // Output: Monkey D. Garp
// ES5 using constructor function
function Person() {
let _name = '';
Object.defineProperty(this, 'name', {
get: function() {
return _name;
},
set: function(value) {
_name = value;
},
enumerable: true,
configurable: true
});
}
const person2 = new Person();
person2.name = 'Monkey D. Dragon';
console.log(person2.name); // Output: Monkey D. Dragon
// ES6 using classes
class newGen {
constructor() {
this._name = '';
}
get firstName() {
return this._name;
}
set firstName(value) {
this._name = value;
}
}
const top1 = new newGen();
top1.name = 'Monkey D. Luffy';
console.log(top1.name); // Output: Monkey D. Luffy
// ES6+ using class public field proposal
class GodLevel {
#name = '';
get name() {
return this.#name;
}
set name(value) {
this.#name = value;
}
}
const sunGod = new GodLevel();
sunGod.name = 'neka';
console.log(sunGod.name); // Output: neka
// function useState(initialValue) {
// let state = initialValue;
// function setState(newValue) {
// state = newValue;
// }
// return [
// () => state, // Getter function
// setState, // Setter function
// ];
// }
// const [getValue, setValue] = useState("name");
// console.log(getValue()); // Output: "name"
// setValue("newValue");
// console.log(getValue()); // Output: "newValue"
// const [getObjectValue, setObjectValue] = useState({ name: "ullas" });
// console.log(getObjectValue()); // Output: { name: 'ullas' }
// setObjectValue({ name: "newValue" });
// console.log(getObjectValue()); // Output: { name: 'newValue' }
// const [isOpen, setOpen] = useState(true);
// console.log(isOpen()); // Output: true
// setOpen(false);
// console.log(isOpen()); // Output: false
// -------
function useState(initialValue) {
let state = initialValue;
function setState(newValue) {
state = newValue;
}
const stateProxy = new Proxy({}, {
get: function(target, prop) {
if (prop === 'value') {
return state;
}else if(prop === 'type'){
return typeof state
}
return target[prop];
},
set: function(target, prop, value) {
if (prop === 'value') {
setState(value);
} else {
target[prop] = value;
}
return true;
},
});
return [
stateProxy,
stateProxy
];
}
const [getValue, setValue] = useState("name");
console.log(getValue.value); // Output: "name"
// custom get type of the data
console.log("return the type of data:",getValue.type);
setValue.value = "newValue";
console.log(getValue.value); // Output: "newValue"
// ----
const [getObjectValue, setObjectValue] = useState({ name: "ullas" });
console.log(getObjectValue.value); // Output: { name: 'ullas' }
// custom get type of the data
console.log("return the type of data:",getObjectValue.type);
setObjectValue.value = { name: "newValue" };
console.log(getObjectValue.value); // Output: { name: 'newValue' }
// ----
const [isOpen, setOpen] = useState(true);
console.log(isOpen.value); // Output: true
// custom get type of the data
console.log("return the type of data:",isOpen.type);
setOpen.value = false;
console.log(isOpen.value); // Output: false