Web Front-end Basics - ES5
ES History
- 1997: ES1 became the first version of the Javascript language standard.
- 2009: ES5, fully supported in all browers.
- 2015: ES2015/ES6 released in 2015. Changed to annual release cycle.
- Asynchronouse Javascript
- AJAX and API calls
- Modern dev setups(Webpack and Babel)
- 2016/2017/2018/2019/…: ES2016/ES2017/ES2018/ES2019/…
Using transpiling and polyfilling to convert to ES5.
Javascript Basics
Falsy and Truthy Values
The following values are considered by Javascript to be truthys:
- Object:
{}
- Array:
[]
- Not empty string:
"anything"
- Number other than zero:
3.14
- Date:
new Date();
The following values are considered by Javascript to be falseys:
undefined
null
0
: Even if a variable is assigned0
, but it still tells it’s undefined when testing withif
, it’s a common pattern in javascript to test a variable whether it’s undefined by usingif(variable || variable === 0)
. See more here''
: empty string value.NaN
: Not a number
Double exclamation marks
!!
is used to cast a Javascript variable to boolean:
1 | var name = "Brain"; |
The JavaScript engine that is executing your code will attempt to convert(or coerce) a value to a boolean when necessary, such as when evaluated in an if-statement.
Equal Operations
Always use ===/!==
to compare in javascript, see here.
Function Expression and Function Declaration
1 | // Function declaration |
Arrays
1 | // could store elements of different data types |
Javascript Engine
Execution Context
A new execution context is created on top of the current execution context every time a function gets called. There’re 2 phases for an execution context to be put on the execution stack:
- Creation phase:
- Creation of the Variable Object(VO):
- The argument object is created, containing all the arguments that were passed into the function
- Function declarations are scanned: for each function, a property is created in the Variable Object, pointig to the function.
- Variable declarations are scanned: for each variable, a property is created in the Variable Object, and set to
undefined
.
- Creation of the Scoping Chain: Each new function creates a scope, it stores all the Variable Object up to global scope. The only way to create a new scope is to write a new function.
- Lexical scoping(作用域继承)): A function that is lexically within another function gets access to the scope of the outer function.
- Determine value of the
this
variable- Regular function call:
this
keyword points to the global object(thewindow
object in browser) - Method call:
this
keyword points to the object that is calling the method.- Inner function defined inside a method,
this
keyword still points to the global object! this
keyword only gets assigned when the function is called, which means the value ofthis
keyword is determined instantly at runtime.
- Inner function defined inside a method,
- Regular function call:
- Creation of the Variable Object(VO):
- Execution phase: run the function that generated the current execution context line by line.
Global Context: for variables and functions not inside of any function. Associated with window
object.
A function like below may cause a series of changes like below:
1 |
|
Anonymouse functions’ scoping chain remains the same as the declared functions.
Hoisting(提升)
Functions and variables are available before the execution actually get started. They are hoisted in different ways:
- Functions: functions are already defined before the execution phase starts. Hositing only works for Function Declarations over Function Expressions.
- Variables: available are set to
undefined
and will be defined in the execution phase.
Event & Event Loop
See details here.
Execution Stack
: stores a set of execution context, the first execution context is theGlobal Execution Context
. Each time a function is executed, a new execution context bound to that function is created and pushed into the execution stack.Message Queue
: Stores all functions that are to be executed. Event handler functions or async functions are all stored here. They are in form ofcallback
functions.Event Loop
: The job of the event loop, is to constantly monitor theMessage Queue
andExecution Stack
, and to push the first callback function in line onto the execution stack as soon as the stack is empty(theGlobal Execution Context
is idle).Event Listener
: The event listener is normally a function, which also has its own execution context.
Message Queue
A JavaScript runtime uses a message queue, which is a list of messages to be processed. Each message has an associated function which gets called in order to handle the message. The runtime handles message from the oldest. To do so, the message is removed from the queue and its corresponding function is called with the message as an input parameter. As always, calling a function creates a new stack frame for that function’s use.
Each message is processed completely before any other message is processed. It cannot be pre-empted and will run entirely before any other code runs(prevent modify data the function manipulates). A downside of this model is that if a message takes too long to complete, the web application is unable to process user interactions like click or scroll. A good practice to follow is to make message processing short and if possible cut down one message into several messages.
A very interesting property of the event loop model is that JavaScript, unlike a lot of other languages, never blocks. Handling I/O is typically performed via events and callbacks, so when the application is waiting for an IndexedDB
query to return or an XHR
request to return, it can still process other things like user input.
setTimeout
The function setTimeout
is called with 2 arguments:
- a message to add to the queue, and a time value (optional; defaults to 0).
- The time value represents the (minimum) delay after which the message will actually be pushed into the queue.
If there is no other message in the queue, and the stack is empty, the message is processed right after the delay. However, if there are messages, the setTimeout message will have to wait for other messages to be processed. For this reason, the second argument indicates a minimum time—not a guaranteed time.
Prototype Inheritance
Every javascript object has a property called prototype
. The Object
object is the root constructor of every other object. This is also known as Prototype Chain
.
new
operator will create an new empty object and call the function constructor withthis
keyword points to the empty object. Which meansthis
keyword will be set as the object’s scope.instandOf
:object.create()
: receive an object parameter as the new object’s prototype, and another arguments object describing the properties.
Variables that associated with an object contains the reference to that object in memory.
Functions
Passing Functions as Arguments
Behaves like delegates.
Functions Returning Functions
Returns a delegate from functions.
Immediately Invoked Funtion Expression(IIFE)
An IIFE looks something like below:
1 | (function (goodLuck) { |
IIFE creates a new function scope and variables defiend inside an IIFE will not be visible outside the function.
Closures
An inner function has always access to the variables and parameters of its outer function, even after the outer function has returned. What makes it happen is the scope chain always stay intact despite the execution context.
Bind, Call and Apply
function.call({target-object}, params...)
actually is borrowing method from other objects.function.apply({target-object}, [params])
works the same way as call
but accepts the arguments as array.
function.bind()
returns a function copy with preset arguments:
1 | var johnFriendly = john.presentation.bind(john, "friendly"); |
This is called function carrying
.