Just a Reference to look into with the correct Terms that i keep forgetting
WIP:
- Todo create index
- Split into sections
- Object Literal
const obj = {}
- Array Literal
const arr = []
- Scope Managing
- LeftSide(Target of Assignment) | RightSide (Source) declaration
function wat() {
var wth = 'wth'
}
wat() // Right Hand Side Value (Source Declaration)
- go resolve the wat expression and find out its value (in this case a function
- go to the parenthesis () - almost as if they were operators - and execute
Lexical Scope is fixed (at compile time)
this var is always reference
Formal Declaration
var functionDeclaration = 'identifier'
function wat(formal declaration for a parameter)
All Variable and Function Declarations have been compiled away
- var omg = 'omg'
wat() {
- var wat = 'wat'
dahell () {
}
}
wat()
After Compile at Runtime
function wat() {
lulz = 'imglobalnow lulz'
}
Implicitly create a Global as a result of assigning to a variable that was never declared:
Fix:
- Dont do it (it's bad and slower to create a var at runtime)
- 'use strict' => reference Error is then thrown
btw: Global Vars are not created for functions <3
wth() // reference error
var wat = 'wat'
function watify() {
console.log(wat) => undefined
var wat = 'shadowed' // Wat will be shadowed at compile time,
r.i.p accessing this lexically at runtime ( window.wat would
work if we are one level deep, but with more nesting it wouldnt)
}
functions without a return statement implicitly return undefined
function declaration() {}
var clickHand = function {}
var named = function declaration () {
declaration() // is now available within its own scope
}
Always prefer Named Function Expressions over Anonymous Function Expressions
- Reliable and Handy function self-reference (identifier is read only)
- Debuggability: Uses name in stack trace
- Code Readability
Predictable
function fx () {
var lc = 'lc'
function x () {
console.log(lc) // lexical, aka always bound to scope
}
lc()
}
fx ()
Flexible: Function resolves references to variables dynamically depending on where it is called Theoretical Example:
function wat() {
console.log(sc)
}
function sc () {
var sc = 'ss'
foo();
}
sc(); // ss
Ability of a Function to 'remember' its lexical scope, even when it is executed outside its lexical scope
Not truly a thing: It's actually a way to think about the 2 pass compilation process in JS.
- Vars and lexical scopes are parsed
- Values are then assigned Thats why we can declare a var after already haven given it a value and that stuff works
let and const behave differently
var foot = new shoot();
- A brand new Empty Object is created
- The newly created object is linked to another Object
- The newly created object is passed in as the this context to the function call
- Imply that it return this (itself)
Whats this going to point to
- new (yup, it overrides bind)
- call()/apply() (bind() uses apply()
- context object (o2.foo())
- default: global object (except strict mode)
A function with closure state that keeps track of some value and it gives you those back when you call it
function add(x, y) {
return x + y
}
var thunk = function() {
return add(10,15);
}
thunk(); // 25
Fn doesnt need arguments except the callback to get the value out
From outside we don't care or know wether the value is there immediately or if we have to wait We pass the callback and the callback is called when a value is ready Eliminates time as a factor Give Callback get value out
function addAsync(x,y,cb) {
setTimeout(function(){
cb(x + y)
}, 1000);
}
var thunk = function(cb) {
addAsync(10,15,cb);
}
thunk(function(sum){
sum; //25
});
function getFile(file) {
var text, callback;
asyncRequest(file, function(response){
if (fn) fn(response);
else text = response;
})
return function(callback){
if (text) callback(text);
else fn = callback;
}
}
var thunk1 = getFile('file1')
var thunk2 = getFile('file2')
var thunk3 = getFile('file3')
thunk1(function(text1) {
console.log(text1)
thunk2(function(text2){
console.log(text2)
thunk3(function(text3){
console.log(text3)
console.log("Complete")
})
})
})
- undefined
- string
- number
- boolean
- object
- function (subtype of object, it's a callable object)
- null (no identity aka null !== typeof null)
- symbol
- NaN
- Infinity, -Infinity
- null
- undefined (void)
- +0, -0
var a = 'a' / 2
a // NaN
typeof a // "number"
isNan('foo') // true WTF => tries to convert it to a number first and then checks if its a Number
- String()
- Number()
- Boolean()
- Function()
- Object()
- Array()
- RegExp()
- Date()
- Error()
Value | Result |
---|---|
null | null |
undefined | "undefined" |
3.14159 | "3.14159" |
0 | "0" |
-0 | "0" //WTF |
[] | "" |
[1,2,3] | "1,2,3" //no brackets :( |
[null, undefined] | "," //WTF |
[[[],[],[]],[]] | [,,,] |
[,,,,] | ',,,' //trailing comma |
{} | "[object Object]" |
{a:2} | "[object Object]" |
Falsy | Truthy |
---|---|
"" | "foo" |
-0, 0, +0 | 23 |
null | {a:1} |
NaN | [1,3] |
false | true |
undefined | function(){...} |
Value | Result |
---|---|
"" | 0 //WTF |
"0" | 0 |
"-0" | -0 |
" 009 " | 9 |
"3.14159" | 3.14159 |
"0 ." | 0 |
".0" | 0 |
"." | NaN //WTF |
false | 0 |
true | 1 |
null | 0 //WTF |
undefined | NaN //WTF |
var foo = '123'
baz = +foo
baz // 123
var baz = Boolean(foo)
! negate operator ! coerce to a boolean (toBoolean()) and flips the parity (!negate operator) ! flip it back
baz = !!foo;
baz = foo ? true : false
let a = 'a'
let c = 'c'
let d = 'c'
const b = () => console.log('b')
const e = () => console.log('e')
a
? b() || (c = d)
: e()
// "c"
Boolean Coercion with ~
~N -> -(N+1)
// indexOf returns -1
~foo,indexOf('f')
Date.now()
// var now = +new Date()
// var foo = 'foo'
var now = new Date // works too shrugs*
Js automatically coerces a primitive to its object wrapper counterpart (in this case Number:) That is why we can use .toString() without casting it to a String Object
baz = 456;
foo = baz.toString();
foo // '456'
Dont user new String() new Number () They create object
new String () => Dev Console String in italics new String () => wrapper object around the primitive String => Object
As function String () doesnt wrap, it just coerces
0 primitive is truthy 0 as Obj
false as Boolean primitive is falsy false as Boolean object is truthy
new Array(42) // overloaded => now this is the length
sparse Array => empty array => array.length console: 42
map => they dont exist, empty/phantom slots
JS doesn't allocate memory, creates a linked list and sets the lenght to 42 no perfomance benefit
use the literal
imperative - declarative
new Object() <=> { a: 1, b: 2}
Regexp
foo = new RegExp("a*b", "g") // use if it the pattern has to be dynamic
foo = /a*b/g