luisquike
10/3/2017 - 3:42 PM

JS skillset

Reopilation of book Up&Going from https://github.com/getify/You-Dont-Know-JS

//Objects
var obj = {
	a: "hello world",
	b: 42,
	c: true
};

obj.a;		// "hello world"
obj.b;		// 42
obj.c;		// true

obj["a"];	// "hello world"
obj["b"];	// 42
obj["c"];	// true

//Arrays
var arr = [
	"hello world",
	42,
	true
];

arr[0];			// "hello world"
arr[1];			// 42
arr[2];			// true
arr.length;		// 3

typeof arr;		// "object"

//Functions
function foo() {
	return 42;
}

foo.bar = "hello world";

typeof foo;			// "function"
typeof foo();		// "number"
typeof foo.bar;		// "string"

//Built-In Type Methods

var a = "hello world";
var b = 3.14159;

a.length;				// 11
a.toUpperCase();		// "HELLO WORLD"
b.toFixed(4);			// "3.1416"

//Coercion

var a = "42";
var b = Number( a );
a;				// "42"
b;				// 42 -- the number!

var a = "42";
var b = a * 1;	// "42" implicitly coerced to 42 here
a;				// "42"
b;				// 42 -- the number!

//Truthy & Falsy

//specific list of "falsy" values
"" //(empty string)
0, -0, NaN //(invalid number)
null, undefined
false

//any value that's not on this "falsy" list is "truthy
"hello"
42
true
[ ], [ 1, "2", 3 ] //(arrays)
{ }, { a: 42 } //(objects)
function foo() { .. } //(functions)

//Equality
var a = "42";
var b = 42;

// == checks for value equality
a == b;			// true
// === checks for value and type equality
a === b;		// false

var a = [1,2,3];
var b = [1,2,3];
var c = "1,2,3";
a == c;		// true
b == c;		// true
a == b;		// false

//NaN is neither greater-than nor less-than any other value.
var a = 42;
var b = "foo";
a < b;		// false
a > b;		// false
a == b;		// false

//Hoisting
var a = 2;
foo();					// works because `foo()`declaration is "hoisted"
function foo() {
	a = 3;
	console.log( a );	// 3
	var a;				// declaration is "hoisted" to the top of `foo()`
}
console.log( a );	// 2

//Nested Scopes
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();

//If-Else
if (a == 2) {
	// do something
}
else if (a == 10) {
	// do another thing
}
else if (a == 42) {
	// do yet another thing
}
else {
	// fallback to here
}

//Switch
switch (a) {
	case 2:
		// do something
		break;
	case 10:
		// do another thing
		break;
	case 42:
		// do yet another thing
		break;
	default:
		// fallback to here
}

//The ? operator
var a = 42;
var b = (a > 41) ? "hello" : "world";

//Assign functions
var foo = function() {
	// Anonymous function
};
var x = function bar(){
	// Named function
};

//Immediately Invoked Function Expressions (IIFEs)
(function IIFE(){
	console.log( "Hello!" );
})();
// "Hello!"

function foo() { .. }
// `foo` function reference expression,
// then `()` executes it
foo();
// `IIFE` function expression,
// then `()` executes it
(function IIFE(){ .. })();

//Hoisting into IIFE
var a = 42;
var x = (function IIFE(){
	var a = 10;
	console.log( a );	// 10
})();
console.log( a );		// 42

//Closure
//You can think of closure as a way to "remember" and continue 
//to access a function's scope (its variables) even once the 
//function has finished running.
function makeAdder(x) {
	// parameter `x` is an inner variable

	// inner function `add()` uses `x`, so
	// it has a "closure" over it
	function add(y) {
		return y + x;
	};
	return add;
}
// `plusOne` gets a reference to the inner `add(..)`
// function with closure over the `x` parameter of
// the outer `makeAdder(..)`
var plusOne = makeAdder( 1 );
// `plusTen` gets a reference to the inner `add(..)`
// function with closure over the `x` parameter of
// the outer `makeAdder(..)`
var plusTen = makeAdder( 10 );
plusOne( 3 );		// 4  <-- 1 + 3
plusOne( 41 );		// 42 <-- 1 + 41
plusTen( 13 );		// 23 <-- 10 + 13
// When we call makeAdder(1), we get back a reference to its inner add(..) that remembers x as 1. We call this function reference plusOne(..).
// When we call makeAdder(10), we get back another reference to its inner add(..) that remembers x as 10. We call this function reference plusTen(..).
// When we call plusOne(3), it adds 3 (its inner y) to the 1 (remembered by x), and we get 4 as the result.
// When we call plusTen(13), it adds 13 (its inner y) to the 10 (remembered by x), and we get 23 as the result.

//Closure with module
function User(){
	var username, password;
	function doLogin(user,pw) {
		username = user;
		password = pw;
		// do the rest of the login work
	}
	var publicAPI = {
		login: doLogin
	};
	return publicAPI;
}
// create a `User` module instance
var fred = User();
fred.login( "fred", "12Battery34!" );

//This identifier
//It's important to realize that this does not refer to the function itself
function foo() {
	console.log( this.bar );
}
var bar = "global";
var obj1 = {
	bar: "obj1",
	foo: foo
};
var obj2 = {
	bar: "obj2"
};
// --------
foo();				// "global"
obj1.foo();			// "obj1"
foo.call( obj2 );	// "obj2"
new foo();			// undefined
// 1) foo() ends up setting this to the global object in non-strict mode -- in strict mode, this would be undefined and you'd get an error in accessing the bar property -- so "global" is the value found for this.bar.
// 2) obj1.foo() sets this to the obj1 object.
// 3) foo.call(obj2) sets this to the obj2 object.
// 4) new foo() sets this to a brand new empty object.

//Prototypes
// When you reference a property on an object, 
// if that property doesn't exist, JavaScript will automatically 
// use that object's internal prototype reference to find 
// another object to look for the property on. 
var foo = {
	a: 42
};
// create `bar` and link it to `foo`
var bar = Object.create( foo );
bar.b = "hello world";
bar.b;		// "hello world"
bar.a;		// 42 <-- delegated to `foo`
// The a property doesn't actually exist on the bar object, 
// but because bar is prototype-linked to foo, 
// JavaScript automatically falls back to looking for a on the foo object, 
// where it's found.

//Polyfilling
if (!Number.isNaN) {
	Number.isNaN = function isNaN(x) {
		return x !== x;
	};
}   

//Transpiling
function foo(a = 2) {//New enviroments
	console.log( a );
}
foo();		// 2
foo( 42 );	// 42 

function foo() {//Old enviroments
	var a = arguments[0] !== (void 0) ? arguments[0] : 2;
	console.log( a );
}

//Non JS
//The document variable exists as a global variable when your code is running in a browser. 
//It's not provided by the JS engine, nor is it particularly controlled by the JavaScript specification
//It's a special object, often called a "host object.". It's provided by DOM API
var el = document.getElementById( "foo" );

//alert(..) is provided to your JS program by the browser, not by the JS engine itself.
//The same goes with console.log(..)

//Scopes
//It's not enough to have anecdotal fuzzy beliefs about scope.
//The JS engine compiles your code right before (and sometimes during!) execution.

//this & Object Prototypes
// The "this" keyword is dynamically bound based on how the function 
// in question is executed, and it turns out there are four simple 
// rules to understand and fully determine this binding.

//Async and Performance
// callbacks as the primary method of enabling asynchrony.
// Generators introduce a new mode of execution for JS functions, 
// whereby the generator can be paused at yield points and be resumed asynchronously later.