Skip to content

Commit 5cd67be

Browse files
author
Kevin Jose
committed
[14/5/2020][Javascript info] notes, object to primitive conversion
1 parent 9962abb commit 5cd67be

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed

may-2020/javascript_info/objects.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,3 +223,154 @@ ladder
223223
.down()
224224
.showStep(); // 1
225225
```
226+
227+
### constructor operator - new
228+
229+
- new allows to create template based objects
230+
231+
```javascript
232+
function User(name) {
233+
this.name = name;
234+
this.isAdmin = false;
235+
}
236+
let user = new User('Jack');
237+
console.log(user.name, user.isAdmin); // Jack, false
238+
```
239+
240+
- 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+
function User(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 = new User('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+
function User(name) {
258+
if (!new.target) {
259+
return new User(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+
function User(name) {
272+
this.name = name;
273+
this.sayHi = function () {
274+
console.log(this.name);
275+
};
276+
}
277+
let john = new User('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+
return this.name;
364+
}
365+
// for hint == 'number' or default
366+
valueOf(){
367+
return this.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

Comments
 (0)