You Don't Know JS Yet (2nd edition, work-in-progress)
Book Details
Full Title: You Don't Know JS Yet (2nd edition, work-in-progress)
Author: Kyle Simpson
ISBN/URL:
Reading Period: 2019.10.14–2019.12.17
Source: Recommended by the Internet after Google search on ways to learn modern JavaScript
General Review
-
Read this book if you want to get a good (albeit opinionated at times) understanding of how JavaScript works under the hood.
-
This allows understanding of the quirks of JavaScript.
-
Specific Takeaways
-
After reading this book, I understand the binding behavior of
this
:-
In order to determine what is
this
during the execution of a function, we examine the call site and observe how the method is called. The list below is in descending precedence, andtheFunction()
represents the function containing thethis
:-
someVar = new theFunction(...)
–>this
is set to a newly created object -
someVar = theFunction.bind(someObj)(...)
–>this
is set tosomeObj
-
someVar = anotherObj.theFunction(...)
–>this
is set toanotherObj
-
theFunction(...)
–>this
is set to the current lexical scope (e.g., thewindow
object if called directly in browser developer console)
-
-
Arrow functions will inherit the
this
in the context. As such, if a functionnamedFunction()
returns an arrow function with refers tothis
, thatthis
will be the one whennamedFunction()
was originally called.
-
-
After reading this book, I understand the details of object property access:
-
It is helpful to consider two aspects of property: (1) whether it is
enumerable
, and (2) whether it is directly owned by the object, or is further up the prototype chain. -
Different in-built statements sometimes behave differently depending on (1) and (2) above:
-
The conditional
('a' in someObj)
returnsTrue
even if'a'
is notenumerable
and is not directly owned. -
The
for..in
loop iterates over the keys of allenumerable
properties, whether directly or indirectly owned -
obj.keys()
returns the keys of enumerable properties that are directly owned.
-
-
-
After reading this book, I learned that it is possible to:
-
change whether a property is
enumerable
,writable
, and/orconfigurable
-
define getters and setters for properties (properties accessed using setters and getters are called
accessor descriptors
whereas properties accessed directly are calldata descriptors
) -
define an iterator on an object to allow usage of
for..of
loop on any objects (and not justArrays
)
-
-
After reading this book, I understand that JavaScript can be understood as a compiled language. For example, variables declarations like
var a;
will be hoisted to the top of the scope (and initialized as undefined) even if it exist later in the actual code.-
As another example, syntax error in a later part of the file will prevent execution of valid code earlier in the file. (E.g., if that is a valid
console.log('Hello, world')
in the first line, and a syntax error in the second line, the "Hello, world" will not be printed. Contrast with Python, where the code will execute until the interpreter encounters the first syntax error.)
-
-
After reading this book, I understand that JavaScript's object-oriented might be seen in at least two ways:
-
the usual parent-child inheritance paradigm (i.e., overriding parent's methods in the child and using polymorphism)
-
a delegation of behavior via traversal of prototype links (i.e., not overriding parent's method, but instead naming the parent and child method in a way that is more descriptive of what each actually does)
-
-
JavaScript has primitive types (e.g.
string
) and natives / built-ins (e.g.String
(notice the uppercaseS
)).-
Many "type-specific" behaviors are defined on the prototype of the corresponding natives (e.g.,
Number.prototype.toString()
) -
Primitive types will be automatically boxed with an object wrapper (i.e., converted into the corresponding natives) in certain operations (e.g.,
let a = 42; a.toString()
will box the primitivenumber
into aNumber
before callingtoString()
.
-
-
There are specific not-so-complex rules governing implicit type coercion, that results in the myriad of weird behaviors that JavaScript is known for.
-
One intereseting thing about using JavaScript for front-end development is that the same source code will be runned in different enviroments supporting different features of JavaScript.
-
As such, it might be fruitful to consider writing code that works in all environments, but will take advantage of the newer features if available.
-
For example:
-
Check for availability of APIs, and use polyfill if not available.
-
Check for availability of syntax, and load different source files accordinglye
-
Tail Call Optimization (TCO) is only available in ES6, we can write code that will make use of TCO if available, but will still run without error even without TCO. (See example here).
-
-
-
JavaScript offers certain more "advanced" data structures:
-
Map
in JavaScript allows using objects as keys (normal object doesn't). -
TypedArrays
create a structuredview
over underlying binary buffer for structured access (i.e., I can access and modify aint32
array view over a binary buffer).-
The
.sort()
method onTypedArrays
sorts numerically (whereas the.sort()
method on usualarray
sorts alphabetically, so10
comes before2
).
-
-
Set
provides the usual set semantics.
-
-
JavaScript supports meta-programming via proxy objects and overwriting of "Well Known Symbols". (Note:
symbol
is a JavaScript primitive type.)-
For example, it is possible to overwrite what happens when a function is called.
-
-
When there are hard-to-debug errors, consider whether the program has exceeded certain limits such as:
-
maximum number of characters allowed in a string literal (not just a string value)
-
size (bytes) of data that can be sent in arguments to a function call (aka stack size)
-
number of parameters in a function declaration
-
maximum depth of non-optimized call stack (i.e., with recursion): how long a chain of function calls from one to the other can be
-
number of seconds a JS program can run continuously blocking the browser
-
maximum length allowed for a variable name
-
and other possible limits
-
-
Note that
console.log()
might be executed asynchronously by the JavaScript enviroment (e.g., the browser. The code below may log2
instead of1
:
let a = 1;
console.log(a);
a++;
-
If more performance is desired from JavaScript code, consider (a) multi-threading with Web Workers and/or (b) asm.js.
To Internalize Now
-
Things I should put into my day-to-day toolbox include:
-
Consider using the various
TypedArrays
,Map
andSet
data structures
-
To Learn/Do Soon
-
Nil
To Revisit When Necessary
-
This book covers the following topics in detail, I have not immediate need for them right now, but I can revisit the book in the future when needed
-
There are practice tasks to reinforce / refresh my understanding of the concepts covered at https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/get-started/apB.md
Other Resources Referred To
-
I should check out the following references made in the book
-
I should check out MDN Web Docs on Promise API when doing JavaScript work:
-
I should check out the MDN Web Docs on Generator functions when doing serious JavaScript work:
-
I should check the appendix on asyncquence to understand the thought process behind designing and building an abstraction on top of the Promises API: