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
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
25
37
26
-
####Built-in Types
38
+
# Built-in Types
27
39
JavaScript defines seven built-in types, which can be broken down into two categories: `Primitive Type` and `Object`.
28
40
29
41
There are six primitive types: `null` , `undefined` , `boolean` , `number` , `string` , `symbol `.
@@ -120,7 +132,7 @@ ToPrimitive([]) == 0
120
132
1. If it's an object, `toPrimitive` is used.
121
133
2. If it's a string, `unicode` character index is used to compare.
122
134
123
-
####Typeof
135
+
# Typeof
124
136
125
137
`typeof` can always display the correct type of the primitive types, except `null`
126
138
```js
@@ -160,7 +172,77 @@ let undefined = 1
160
172
a ===void0
161
173
```
162
174
163
-
#### New
175
+
# Type Conversion
176
+
177
+
## Converting to Boolean
178
+
179
+
Except `undefined`, `null`, `false`, `NaN`, `''`, `0`, `-0`, all of the values, including objects, are converted to `true`.
180
+
181
+
## Objects to Primitive Types
182
+
183
+
When objects are converted, `valueOf` and `toString` will be called, respectively in order. These two methods can also be overridden.
184
+
185
+
```js
186
+
let a = {
187
+
valueOf() {
188
+
return0
189
+
}
190
+
}
191
+
```
192
+
193
+
## Arithmetic Operators
194
+
195
+
Only for additions, if one of the parameters is a string, the other will be converted to the string as well. For all other operations, as long as one of the parameters is a number, the other will be converted to a number.
196
+
197
+
Additions will invoke three types of type conversions: to primitive types, to numbers, and to string.
`toPrimitive` in the above figure is converting objects to primitive types.
221
+
222
+
`===` is usually recommended to compare to values. However, if you would like to know if a value is `null`, you can use `xx == null`.
223
+
224
+
Let's take a look at an example `[] == ![] // -> true`. The following explains why the expression evaluates to `true`.
225
+
226
+
```js
227
+
// [] converting to true, then take the opposite to false
228
+
[] ==false
229
+
// with #8
230
+
[] ==ToNumber(false)
231
+
[] ==0
232
+
// with #10
233
+
ToPrimitive([]) ==0
234
+
// [].toString() -> ''
235
+
''==0
236
+
// with #6
237
+
0==0// -> true
238
+
```
239
+
240
+
## Comparison Operator
241
+
242
+
1. If it's an object, `toPrimitive` is used.
243
+
2. If it's a string, `unicode` character index is used to compare.
244
+
245
+
# New
164
246
165
247
1. Create a new object
166
248
2. Chained to prototype
@@ -226,7 +308,7 @@ new (Foo.getName());
226
308
For the first function, `Foo.getName()` is executed first, so the result is 1;
227
309
As for the latter, it firstly executes `new Foo()` to create an instance, then finds the `getName` function on `Foo` via the prototype chain, so the result is 2.
228
310
229
-
####This
311
+
# This
230
312
231
313
`This`, a concept that many people will confuse, is not difficult to understand, as long as you remember the following rules
232
314
@@ -271,7 +353,7 @@ console.log(a()()());
271
353
Actually , the arrow function does not have `this` , `this` in the above function only depends on the first function outside that is not arrow function . In above case , `this` is default to `window` because calling `a` matches the first situation in the above codes . And , what `this` is bound to will not be changed by any code once `this` is bound to the context
272
354
273
355
274
-
#### instanceof
356
+
#Instanceof
275
357
276
358
The `instanceof` operator can correctly judge the type of the object , bacause it’s internal mechanism is to find out if `prototype` of this type can be found in the prototype chain of the object
277
359
let’s try to implement it
@@ -292,7 +374,7 @@ function instanceof(left, right) {
292
374
}
293
375
```
294
376
295
-
#### scope
377
+
#Scope
296
378
297
379
Executing JS code would generate execution environment , as long as the code is not written in a function , it belongs to the global execution environment . The code in a function will generate function execution environments , but only two (there’s an `eval`, which basically will not be used, so you can think of only two execution environments))
298
380
@@ -331,7 +413,7 @@ var b = 'Hello world'
331
413
332
414
Using `var` is more likely to make mistake , thus ES6 introduces a new keyword `let` . `let` has an important feature that it can’t be used before declared , which mismatches the often saying that `let` doesn’t have the ability of hoisting . Indeed, `let` hoists declared , but does not assign a value, because the temporary dead zone.
333
415
334
-
####Closure
416
+
# Closure
335
417
336
418
The definition of a closure is simple: Function A returns a function B, and function B uses a variable of function A, and the function B is called a closure.
337
419
@@ -415,7 +497,7 @@ For `let`, it will create a block-level scope, which is equivalent to:
The shallow copy only solves the problem of the first layer. If the object contains objects, then it returns to the beginning topic that the values of both share the same reference. To solve the problem, we need to introduce deep copy.
542
624
543
-
##### deep copy
625
+
## Deep copy
544
626
545
627
The problem can usually be solved by `JSON.parse(JSON.stringify(object))`
546
628
@@ -614,7 +696,7 @@ var obj = {a: 1, b: {
614
696
constclone=awaitstructuralClone(obj);
615
697
```
616
698
617
-
#### the differences between call, apply, bind
699
+
# The differences between call, apply, bind
618
700
619
701
Firstly, let’s tell the difference between the former two.
620
702
@@ -635,7 +717,7 @@ getValue.call(a, 'yck', '24')
635
717
getValue.apply(a, ['yck', '24'])
636
718
```
637
719
638
-
##### simulation to implement `call` and `apply`
720
+
## simulation to implement `call` and `apply`
639
721
640
722
We can consider how to implement them from the following points
641
723
@@ -701,7 +783,7 @@ Function.prototype.myBind = function (context) {
701
783
}
702
784
```
703
785
704
-
#### Promise implementation
786
+
# Promise implementation
705
787
706
788
`Promise` is a new syntax introduced by ES6, which resolves the problem of callback hell.
707
789
@@ -894,7 +976,7 @@ The above codes, which is implemented based on the Promise / A+ specification,
`Debounce` and `Throttle` are different in nature. `Debounce` is to turn multiple executions into the last execution, and `Throttle` is to turn multiple executions into execution at regular intervals.
900
982
@@ -1008,7 +1090,7 @@ function b() {
1008
1090
```
1009
1091
1010
1092
1011
-
# async and await
1093
+
# Async and await
1012
1094
1013
1095
A function with `async`, then the function will return a `Promise`.
1014
1096
@@ -1063,4 +1145,110 @@ You may have doubts about the above code, here explain the principle
1063
1145
- First the function `b` is executed. The variable `a` is still 0 before execution `await10`, Because the `generators` are implemented inside `await` and `Generators` will keep things in the stack, so at this time `a =0` is saved
1064
1146
- Because `await` is an asynchronous operation, `console.log('1', a)` will be executed first.
1065
1147
- At this point, the synchronization code is executed and asynchronous code is started. The saved value is used. At this time, `a =10`
1066
-
- Then comes the usual code execution
1148
+
- Then comes the usual code execution
1149
+
1150
+
# Proxy
1151
+
1152
+
Proxy is a new feature since ES6. It can be used to define operations in objects.
1153
+
1154
+
```js
1155
+
let p =newProxy(target, handler);
1156
+
// `target` represents the object of need to add the proxy
1157
+
// `handler` customizes operations in the object
1158
+
```
1159
+
1160
+
Proxy can be handly for the implementation of data binding and listening.
Binary computations in float numbers are different from those in integers. For multiplications, only the float bits are computed, while the integer bits are used for the binaries for each bit. Then the first bit is used as the most significant bit. Therefore we get `0.1=2^-4*1.10011(0011)`.
1204
+
1205
+
`0.2` is similar. We just need to get rid of the first multiplcation and get `0.2=2^-3*1.10011(0011)`.
1206
+
1207
+
Back to the double float for IEEE 754 standard. Among the 64 bits, one bit is used for signing, 11 used for integer bits, and the rest 52 bits are floats. Since `0.1` and `0.2` are infinitely cycling binaries, the last bit of the floats needs to indicate whether to round (same as rounding in decimals).
1208
+
1209
+
After rounding, `2^-4*1.10011...001` becomes `2^-4*1.10011(0011*12 times)010`. After adding these two binaries we get `2^-2*1.0011(0011*11 times)0100`, which is `0.30000000000000004` in decimals.
1210
+
1211
+
The native solution to this problem is shown below:
0 commit comments