Skip to content

Instantly share code, notes, and snippets.

@meerasndr
Last active October 23, 2020 11:03
Show Gist options
  • Save meerasndr/0ad2ec5850c9dbbbb3980c1e76ca9ab9 to your computer and use it in GitHub Desktop.
Save meerasndr/0ad2ec5850c9dbbbb3980c1e76ca9ab9 to your computer and use it in GitHub Desktop.

Notes from YDKJS (author: Kyle Simpson) - Book 1 - Up & Going

Values and Types

JS has typed values, not typed variables Built-in types:

  • Strings
  • Number
  • Boolean
  • Null and undefined
  • Object
  • Symbol
	let a;
	a = 23 // typeof a // “number”
	a = ‘hello’  // typeof a // “string”
	a = undefined // typeof a // “undefined”
	a = true  // typeof a // boolean
	a = null // typeof a //object —> weird
	a = { name : ‘Jon’ } //typeof a object

Return value from typeof is always one of above 7 in the list. The value returned is always a string. So:

a = “Meera” 
typeof a is “string” and not string
a = 45
typeof a is “number” and not just number

So, *typeof typeof a* is always **string**

Only values have types in JS, variables are simply containers.

Objects

	let obj = {
		a : “hello”,
		b: 45,
		c : true
	}
	obj.a  //“hello”
	obj.b  //45
	obj.c  //true
	obj[“a”] //“hello”
	obj[“b”] // 45
	obj[“c”] // true
	let b = “a”
	obj[b] //“hello”
	obj[“b”] //45

Arrays Arrays are objects that hold values of any type. Numerically indexed.

let arr = [“hello”, 45, true]
typeof arr // ‘object’
arr.length //3

Functions

function foo(){
	return 42
}
foo.bar = “hello world”
typeof foo // function
typeof foo() //number
typeof foo.bar //string

Built-in Type methods

JS natives and boxing

let a = “hello” // string primitive
let b = 3.14159 // number primitive

a.length // 5
a.toUpperCase() // “HELLO”
b.toFixed(4) //3.1416

The variable b is not an object. So, how does the method toUpperCase() work on a primitive type of string?

There is a String (capital S) object wrapper form, usually called a native, it pairs with the primitive string type. The String object wrapper defines the toUpperCase() method in its prototype. JS automatically boxes the primitive value to its object wrapper counterpart when we do something like ”hello”.toUpperCase()

  • string value -> wrapped by String object
  • number value -> wrapped by Number object
  • boolean value -> wrapped by Boolean object

Comparing values

Result of any comparison is strictly boolean

Coercion explicit coercion

let a = ’42’
let b = Number(a)
a // “42”
b // 42

implicit coercion

let a = ’42’
let b = a - 1 // “42” is implicitly coerced to number 42 here
a // ’42’
b // 41 —> number

Truthy & Falsy When a non-boolean value is coerced into boolean, does it become true or false?

Falsy values in JS:

  • “” (Empty string)
  • 0, -0, NaN
  • null, undefined
  • false

Truthy values in JS:

  • “Hello”
  • 42
  • true
  • [ ], [1, 2, 3] (arrays)
  • { }, { a: 42 } (objects)
  • function foo {}

Equality == and === == checks for value equality with coercion allowed. === checks for value equality without coercion allowed. Called strict equality.

let a = “42”
let b = 42
a == b // true. -> Is “42” (a) coerced as 42. Or, is 42 (b) coerced as “42” ? Answer “42” becomes 42. 
a === b // false

Equality with objects (or arrays & functions) - Will check for equality of reference not values. Arrays are by default coerced to strings with commas in the middle.

let a = [1, 2, 3]
let b = [1, 2, 3]
let c = “1,2,3”
a == c // true
b == c // true
a == b // false !!!

Inequality

  • Applies to numbers obviously 3 < 4
  • Also applies to string “bar” < “foo”

Coercion

let a = 43
let b = “42”
let c = “41”
let x  = “foo”
a > b //true
b > c //true
a > c // true
a > x // false
x > a // false
a == x // false

x is coerced into the invalid number value NaN in the < and > comparisons . NaN is neither greater than nor lesser than any value The == comparison is different. Becomes: 43 == NaN, which is not true

Variables

  • Usual rules apply to variable naming convention
  • must start with a-z, A-Z,$, _
  • can contain 0-9
  • reserved words: for, in, if, null, true, false etc. Function Scopes Hoisting When a var appears inside a scope, that declaration is taken to belong to entire scope and accessible throughout the scope
var a = 3
foo() // function foo is recognized as it is hoisted
function foo(){
	a = 2
	console.log(a)  // 2
}
console.log(a) // 2

Global scope a is changed everywhere in the above code.

var a = 3
foo() // function foo is recognised even before declaration, as it is hoisted
function foo(){
	a = 2
	console.log(a) // 2
	var a  // this is hoisted two lines above, to the top of foo
}
console.log(a) // 3 -> This is the global `a`, not affected by the function scope foo, since foo has its own copy of `a`

It is not a good idea to do variable hoisting, it is confusing. More common to do function hoisting (foo). My note: I think much of this is mitigated with ES6 and arrow functions.

Nested Scopes When a variable is declared, it is available anywhere in the scope. ( declaration using var only) ES5

function foo() {
  var a = 1
  function bar(){
    var b = 2
    function baz(){
      var c = 3
      console.log(a, b, c) // 1, 2, 3
    }
    baz()
    console.log(a, b) // 1, 2
  }
  bar()
  console.log(a) // 1
}
foo()

Conditionals

  • if-else
  • switch
  • ternary operator condition? true : false

Strict Mode

Undeclared variables are automatically globally declared and available in ES5. For eg:

function foo() {
	a = 1 // undeclared
}
 foo()
console.log(a)  //1. the variable a is available globally.

This is undesirable. In strict mode, this is mitigated:

“use strict”
function foo(){
	a = 1 //undeclared
}
foo()
console.log(a) // reference error, a is not defined
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment