Advanced JavaScript Topics
Reference
December 23, 2017
Today I finished the Frontend Masters course, and we dug deeper into some advanced JS topics. Some of it was recap and some of it was new:
Scope
Where variables have their meaning. Some good reminders on the rules of scope:
Scope is created dynamically when we run a function, i.e. when we open a new execution context.
A function has access to its own local scope variables, and inputs to a function are treated as local scope variables. A function has access to variables in higher generation scopes (parent, grandparent, global, window, etc.), but not sibling of child scopes.
A function’s local scope variables are not available anywhere outside that function, regardless of the context it’s called in:
var ACTUAL = null; |
If an inner and an outer variable share the same name, and the name is referenced in the inner scope, the inner scope variable takes precedence. This makes the outer scope variables inaccessible from anywhere within the inner function block. If the name is referenced in the outer scope, the outer value binding will be used.
A new variable scope is created for every call to a function:
var fn = function () { |
An inner function can access both its local scope variables and variables in its containing scope, provided the variables have different names
Between calls to an inner function, that inner function retains access to a variable in an outer scope. Modifying those variables has a lasting effect between calls to the inner function:
var outerCounter = 10; |
Module Pattern
Writing modular functions allows you to set private methods (useGas
) and private properties (gasLevel
) which can only be accessed by privileged functions (go
) to prevent manipulation from the outside on variables that should have set limits:
var Car = function() { |
Underscore.js Library & each(), map(), filter()
The Underscore library adds a lot of methods to the underscore symbol: var _ = {...}
. We did a lot of exercises with _.each()
, _.map()
, and _.filter()
.
_.each()
_.each()
iterates over a list of elements; the iterator comes with three parameters:
_.each([1, 2, 3], function(element, index, wholeThing) { |
To invoke the _.each()
method, the function takes two parameters: a list (array or object) and an iterator function. Note: the native JavaScript forEach
method only works with arrays. With .each()
you can not return any values in the loop. Example:
var pokemon = ["Evie", "Growlithe", "Vulpix"]; |
_.map()
_.map()
iterates over a list of elements and returns a new list of values by mapping each original value through a transformation function (iterator). With _.map()
you must return a value in the iterator function so that there is a value to go into the array.
var makeExcited = function(val) { |
Note that all of these functions work the same way, by running a function as though it has three arguments: function(element, index, wholeThing)
. If the function doesn’t have three arguments, it assumes the first, or first 2 if there are two present.
_.filter()
_.filter()
iterates over a list and returns an array containing only the values that pass the tester function (aka predicate): _.filter(list, tester)
Example:
var evens = _.filter([1,2,3,4,5], function(num) { |
Using Objects Instead of Arrays
These methods work on both arrays and objects. To access the keys & values of objects you can look at the parameters of the function as function(value, key, object)
instead of function(element, index, array)
. Example:
var input = { |
Up Next
Keep working on Hexo site. It’s coming along nicely and definitely want to have it up by the 31st.