Book notes:
“An ECMAScript language type corresponds to values that are directly manipulated by an ECMAScript programmer using the ECMAScript language. The ECMAScript language types are Undefined, Null, Boolean, String, Number, and Object.”
“JavaScript defines seven built-in types: • null • undefined • boolean • number • string • object • symbol-added in ES6! (All of these types except object are called “primitives.”)”
“The typeof operator inspects the type of the given value, and always returns one of seven string values surprisingly, there’s not an exact 1-to-1 match with the seven built-in types we just listed:”
typeof undefined 	===  "undefined"; 	
typeof true 		===  "boolean"; 	
typeof 42 		===  "number"; 	
typeof "42" 		===  "string"; 		
typeof { life: 42 }	===  "object"; 	
typeof Symbol() 	===  "symbol"; 	
typeof null 		===  "object"; 	
“typeof null === "object" It would have been nice (and correct!) if it returned “null”, but this original bug in JS has persisted for nearly two decades,”
“In JavaScript, variables don’t have types —values have types. Variables can hold any value, at any time… A variable can, in one assignment statement, hold a string, and in the next hold a number, and so on.”
“Variables that have no value currently actually have the undefined value. Calling typeof against such variables will return “undefined””
var a;
a; 
b; 
var a;
typeof a; 
typeof b; 
“Many developers will assume “undefined” and “undeclared” are roughly the same thing, but in JavaScript, they’re quite different. undefined is a value that a declared variable can hold. “Undeclared” means a variable has never been declared. JavaScript unfortunately kind of conflates these two terms, not only in its error messages (“ReferenceError: a is not defined”) but also in the return values of typeof, which is “undefined” for both cases.”
“Using delete on an array value will remove that slot from the array, but even if you remove the final element, it does not update the length property, so be careful!”
“While the slot appears to have the undefined value in it, it will not behave the same as if the slot is explicitly set (a[1] = undefined).”
“There will be occasions where you need to convert an array-like value (a numerically indexed collection of values) into a true array, usually so you can call array utilities (like indexof(..), concat(..), forEach(..), etc.) against the collection of values. For example, various DOM query operations return lists of DOM elements that are not true arrays but are array-like enough for our conversion purposes.”
“One very common way to make such a conversion is to borrow the slice(..) utility against the value… As of ES6, there’s also a built-in utility called Array. from(..) that can do the same task:”
“Strings do have a shallow resemblance to arrays-they are array-likes, as above. For instance, both of them have a length property, an indexof(..) method (array version only as of ES5), and a concat(..) method:”
“JavaScript strings are immutable, while arrays are quite mutable.”
“JavaScript has just one numeric type: number. This type includes both “integer” values and fractional decimal numbers.”
“Like most modern languages, including practically all scripting languages, the implementation of JavaScript’s numbers is based on the “IEEE 754” standard, often called “floating-point.” JavaScript specifically uses the “double precision” format (aka “64-bit binary”) of the standard.”
“the toFixed (..) method allows you to specify how many fractional decimal places you’d like the value to be represented with”
“toPrecision(..) is similar, but specifies how many significant digits should be used to represent the value:”
“Starting with ES6 + strict mode, the 0363 form of octal literals is no longer allowed (see below for the new form).”
“For the undefined type, there is one and only one value: undefined. For the null type, there is one and only one value: null. So for both of them, the label is both its type and its value. Both undefined and null are often taken to be interchangeable as either “empty” values or “non” values. Other developers prefer to distinguish between them with nuance.”
“null is an empty value.”
“undefined is a missing value.”
“undefined hasn’t had a value yet.”
“null had a value and doesn’t anymore.”
“The expression void ___“voids” out any value, so that the result of the expression is always the undefined value. It doesn’t modify the existing value; it just ensures that no value comes back from the operator expression:”
var a = 42;
console.log(void a, a); 
“Simple values (aka scalar primitives) are always assigned/passed by value-copy: null, undefined, string, number, boolean, and ES6’s symbol.”
“Compound values— objects (including arrays, and all boxed object wrappers - see Chapter 3) and functions-always create a copy of the reference on assignment or passing.”
“slice(..) with no parameters by default makes an entirely new (shallow) copy of the array.”
"In JavaScript, arrays are simply numerically indexed collections of any value type. strings are somewhat “array-like, but they have distinct behaviors and care must be taken if you want to treat them as arrays. Numbers in JavaScript include both “integers” and floating-point values. Several special values are defined within the primitive types. The null type has just one value, null, and likewise the undefined type has just the undefined value. undefined is basically the default value in any variable or property if no other value is present. The void operator lets you create the undefined value from any other value. numbers include several special values, like NaN (supposedly “Not a Number,” but really more appropriately “invalid number”); +Infinity and - Infinity; and -0. Simple scalar primitives (strings, numbers, etc.) are assigned/passed by value-copy, but compound values (objects, etc.) are assigned/ passed by reference-copy. References are not like references/pointers in other languages they’re never pointed at other variables/references, only at the underlying values.”
“Here’s a list of the most commonly used natives: • String() • Number () • Boolean() • Аггау() • Object() • Function) • RegExp() • Date() • Error () • Symbol ()”
“natives are actually built-in functions.”
“Regular expressions defined in the literal form (/^a*b+/g) are strongly preferred, not just for ease of syntax but for performance reasons-the JS engine precompiles and caches them before code execution. Unlike the other constructor forms we’ve seen so far, RegExp(…) has some reasonable utility: to dynamically define the pattern for a regular expression:”
var name = "Kyle";
var namePattern = new RegExp( "||b(?:" + name + ")+|\b", "ig" );
var matches = someText.match(namePattern);
“There are several predefined symbols in ES6, accessed as static properties of the Symbol function object, like Symbol.create, Symbol.iterator”
“Symbols are not objects, they are simple scalar primitives.”
“JavaScript provides object wrappers around primitive values, known as natives (String, Number, Boolean, etc). These object wrappers give the values access to behaviors appropriate for each object subtype (String#trim() and Array#concat(…)).”
“If you have a simple scalar primitive value like “abc” and you access its length property or some String.prototype method, JS automatically “boxes” the value (wraps it in its respective object wrapper) so that the property/method accesses can be fulfilled.”
“Converting a value from one type to another is often called “type casting,” when done explicitly, and “coercion” when done implicitly”
“in JavaScript, most people refer to all these types of conversions as coercion, so the way I prefer to distinguish is to say “implicit coercion” versus “explicit coercion.””
var a = 42;
var b = a + ""; // implicit coercion
var c = String(a); // explicit coercion
“Some examples are undefineds, functions, (ES6+) symbols, and objects with circular references (where property references in an object structure create a never-ending cycle through each other). These are all illegal values for a standard JSON structure, mostly because they aren’t portable to other languages that consume JSON values.”
“An optional second argument can be passed to JSON.stringify(..) that is called replacer. This argument can either be an array or a function. It’s used to customize the recursive serialization of an object by providing a filtering mechanism for which properties should and should not be included, in a similar way to how toJSON() can prepare a value for serialization.”
“Remember, JSON.stringify(..) is not directly a form of coercion. We covered it here, however, for two reasons that relate its behavior to ToString coercion: 1. string, number, boolean, and null values all stringify for JSON basically the same as how they coerce to string values via the rules of the ToString abstract operation. 2. If you pass an object value to JSON.stringify(..), and that object has a toJSON() method on it, toJSON() is automatically called to (sort of) “coerce” the value to be JSON-safe before stringification.”
“we get the following as the so-called “falsy” values list: • undefined • null • false • +0, -0, and NaN • ""”
“Remember: a value is truthy if it’s not on the falsy list.”
“While not technically coercion itself (since the type doesn’t change!), using bitwise operators (like | or ~) with certain special number values produces a coercive effect that results in a different number value.”
“The ~ operator first “coerces” to a 32-bit number value, and then performs a bitwise negation (flipping each bit’s parity).”
“Technically, if (~a.indexOf(..)) is still relying on implicit coercion of its resultant 0 to false or nonzero to true. But overall, ~ still feels to me more like an explicit coercion mechanism, as long as you know what it’s intended to do in this idiom. I find this to be cleaner code than the previous >= 0/== - 1 clutter.”
“Truncating bits. There’s one more place ~ may show up in code you run accross: some developers use the double tilde ~~ to truncate the decimal part of a number (i.e., “coerce” it to a whole number integer). It’s commonly (though mistakenly) said that this is the same result as calling Math.floor(..). How ~~ works is that the first ~ applies the ToInt32 “coercion” and does the bitwise flip, and then the second ~ does another bitwise flip, flipping all the bits back to the original state. The end result is just the ToInt32 “coercion” (aka truncation). However, ~~ needs some caution/clarification. First, it only works reliably on 32-bit values. But more importantly, it doesn’t work the same on negative numbers as Math.floor(..) does!”
“Just as with all other advice here, use ~ and ~~ as explicit mechanisms for “coercion” and value transformation only if everyone who reads/writes such code is properly aware of how these operators work!”
var a = "42";
var b = "42px";
Number (a); 
parseInt(a); 
Number ( b); 
parseInt( b); 
“Don’t forget that parseInt(..) operates on string values. It makes absolutely no sense to pass a number value to parseInt(..). Nor would it make sense to pass any other type of value, like true, function (){..}, or [1,2,3]… so never use parseInt(..) with a non-string value.”
“As of ES5, parseInt(..) no longer guesses. Unless you say other-wise, it assumes base-10. That’s much nicer. Just be careful if your code has to run in pre-ES5 environments, in which case you still need to pass 10 for the radix.”
“Implicit coercion refers to type conversions that are hidden, with nonobvious side effects that implicitly occur from other actions. In other words, implicit coercions are any type conversions that aren’t obvious (to you).”
“explicit coercion of a symbol to a string is allowed, but implicit coercion of the same is disallowed and throws an error.”
“symbol values cannot coerce to number at all (throws an error either way), but strangely they can both explicitly and implicitly coerce to boolean (always true).”
“The correct description is: “== allows coercion in the equality comparison and === disallows coercion.””
“If you want coercion, use = loose equality, but if you don’t want coercion, use === strict equality.”
“NaN is never equal to itself”
“+0 and -0 are equal to each other”
“In the ES5 spec, clauses 11.9.3.4-5 say: 1) If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y). 2) If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber (x) == Y.”
“Let’s again quote the spec, clauses 11.9.3.6-7: 1) If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y. 2) If Type(y) is Boolean, return the result of the comparison x == ToNumber (y).”
“quoting the ES5 spec, clauses 11.9.3.2-3: 1) If x is null and y is undefined, return true. 2) If x is undefined and y is null, return true.”
var a = null
var b
a == b
a == null
b == null
“If an object/function/array is compared to a simple scalar primitive (string, number, or boolean), the ES5 spec says in clauses 11.9.3.8-9: 1) 1. If Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive (y). 2) If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.”
"0" == false; // true -- UH OH!
false == 0; // true -- UH OH!
false = ""; // true -- UH OH!
false == []; // true -- UH OH!
false == {};// false
"" ==  0; // true -- UH OH!
"" ==  []; // true -- UH OH!
0 == []; // true -- UH OH!
[] == ![]; // true
2 == [2]; true
"" == [nulll]; // true
0 == "\n" ; // true
“When ++ is used in the prefix position as ++a, its side effect (incrementing a) happens before the value is returned from the expression, rather than after as with a++.”
speed reading practice (promo)