You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- function executed with `new`, new empty object created and assigned to `this`, function body executes and mostly adds props to the this object,
241
+
242
+
```javascript
243
+
// calling fn with `new`
244
+
functionUser(name) {
245
+
// capitalizing is just a convention
246
+
// this = {} implicitly
247
+
this.name= name;
248
+
this.isAdmin=false;
249
+
// return this implicity
250
+
}
251
+
let user =newUser('Jack');
252
+
```
253
+
254
+
- to check if function was called with `new` using `new.target`, empty for regular calls and equals the function if called with `new`
255
+
256
+
```javascript
257
+
functionUser(name) {
258
+
if (!new.target) {
259
+
returnnewUser(name);
260
+
}
261
+
this.name= name;
262
+
}
263
+
let john =User('John');
264
+
console.log(john.name); // John
265
+
```
266
+
267
+
- in constructor function, `return` called with object, the object is returned, if `return`, called with primitive, its ignored
268
+
-`methods` can also be added to `this`
269
+
270
+
```javascript
271
+
functionUser(name) {
272
+
this.name= name;
273
+
this.sayHi=function () {
274
+
console.log(this.name);
275
+
};
276
+
}
277
+
let john =newUser('John');
278
+
john.sayHi(); // John
279
+
```
280
+
281
+
### Optional chaining `?.`
282
+
283
+
- optional chaining `?.` is an error-proof way to access nested objects.
284
+
285
+
```javascript
286
+
let user =null;
287
+
console.log(user?.address.street); // undefined and no error
288
+
```
289
+
290
+
- short circuting
291
+
292
+
```javascript
293
+
let user =null;
294
+
let x =0;
295
+
user?.sayHi(x++); // nothing happens
296
+
console.log(x); // 0, value not incremented
297
+
```
298
+
299
+
- value before `?.` must exist.
300
+
301
+
```javascript
302
+
delete user?.name; // delete user.name if user exists.
303
+
```
304
+
305
+
- `?.` checks if the left part is `null/undefined`
306
+
307
+
### Symbols
308
+
309
+
- Symbol is a primitive type for unique identifiers.
310
+
- Symbols are created with Symbol() call with an optional description (name).
311
+
- Symbols are always different values, even if they have the same name.
312
+
- If we want same-named symbols to be equal, then we should use the global registry: `Symbol.for(key)` returns (creates if needed) a global symbol with key as the name. Multiple calls of `Symbol.for` with the same key return exactly the same symbol.
313
+
314
+
- Symbol usecase, hidden properties, symbolic property does not appear in `for..in`
315
+
- System symbols using `Symbol.*`, can be used to alter built in behaviors.
316
+
- Symbols can be displayed using `Object.getOwnPropertySymbols(obj)`, also Reflect.ownKeys(obj) returns all keys including symbols
317
+
318
+
### Object to primitive conversion
319
+
320
+
- what happens when objects are added subtracted or printed
321
+
- All objects are true in boolean context, there are only numeric and string conversion,
322
+
- numberic when we add or subtract or other mathematical functions.
323
+
- string conversions in case of displaying object
324
+
325
+
- fine tune string and numeric conversions using special object methods
326
+
- three variants of type conversions so called as `hints` in the specification - `string`, `number`, `default`(in case of uncertainity) eg: + can be used for addition and concat as well, so for object addition the hint is `default`.
327
+
- to do the conversion, JS tries to find and call the three object methods
328
+
-- obj[Symbol.toPrimitive](hint)
329
+
-- if hint is `string`, obj.toString() and obj.valueOf()
330
+
-- if hint is `number`, obj.valueOf() and obj.toString()
331
+
332
+
```javascript
333
+
let user = {
334
+
name:'John',
335
+
money:1000,
336
+
[Symbol.toPrimitive](hint) {
337
+
console.log(hint);
338
+
return hint ==='string'?this.name:this.money;
339
+
}
340
+
};
341
+
342
+
console.log(user); // John
343
+
console.log(+user); // 1000
344
+
console.log(user +500); // 1500
345
+
```
346
+
347
+
- If there’s no `Symbol.toPrimitive` then JavaScript tries to find them and try in the order:
348
+
- toString -> valueOf for `string` hint.
349
+
- valueOf -> toString otherwise.
350
+
351
+
```javascript
352
+
let user = { name:'John' };
353
+
alert(user); //[object Object]
354
+
alert(user.valueOf() === user); //true
355
+
```
356
+
357
+
```javascript
358
+
let user= {
359
+
name:'John',
360
+
money:1000,
361
+
// for hint == 'string'
362
+
toString(){
363
+
returnthis.name;
364
+
}
365
+
// for hint == 'number' or default
366
+
valueOf(){
367
+
returnthis.money
368
+
}
369
+
}
370
+
371
+
alert(user); // toString -> John
372
+
alert(+user); // valueOf -> 1000
373
+
alert(user+500); // valueOf -> 1500
374
+
```
375
+
376
+
- toString and valueOf must return a primitive (no error but will be ignored, Symbol.toPrimitive, will throw error is no primitive is returned)
0 commit comments