JS Foundation II Flashcards
Execution Context Lexical Environment Hoisting Function Invocation arguments Keyword Variable Environment Scope Chain [[scope]] Function Scope vs Block Scope Global Variables IIFE this keyword call() apply() bind() currying Context vs. Scope
Explain “hoisting”.
Hoisting is a term used to explain the behavior of variable declarations in your code. Variables declared or initialized with the var keyword will have their declaration “moved” up to the top of the current scope, which we refer to as hoisting. However, only the declaration is hoisted, the assignment (if there is one), will stay where it is.
// var declarations are hoisted. console.log(foo); // undefined var foo = 1; console.log(foo); // 1
// let/const declarations are NOT hoisted. console.log(bar); // ReferenceError: bar is not defined let bar = 2; console.log(bar); // 2
Function declarations have the body hoisted while the function expressions (written in the form of variable declarations) only has the variable declaration hoisted.
Explain how “this” works in JavaScript
this is the object that the func is the property of
Methods are functions inside of an object, the left of the ‘dot’
This - hey execution context, who called me?
THIS is dynamically scoped, where its called doesnt matter, how its called matters
Did the object call the function? If not, then THIS is the window
Arrow => functions are lexically bound
Explain why the following doesn’t work as an IIFE: function foo(){ }();. What needs to be changed to properly make it an IIFE?
IIFE stands for Immediately Invoked Function Expressions. The JavaScript parser reads function foo(){ }(); as function foo(){ } and ();, where the former is a function declaration and the latter (a pair of brackets) is an attempt at calling a function but there is no name specified, hence it throws Uncaught SyntaxError: Unexpected token ).
Here are two ways to fix it that involves adding more brackets: (function foo(){ })() and (function foo(){ }()). Statements that begin with function are considered to be function declarations; by wrapping this function within (), it becomes a function expression which can then be executed with the subsequent (). These functions are not exposed in the global scope and you can even omit its name if you do not need to reference itself within the body.
What’s a typical use case for anonymous functions?
They can be used in IIFEs to encapsulate some code within a local scope so that variables declared in it do not leak to the global scope.
As a callback that is used once and does not need to be used anywhere else. The code will seem more self-contained and readable when handlers are defined right inside the code calling them, rather than having to search elsewhere to find the function body.
What’s the difference between .call and .apply?
Both .call and .apply are used to invoke functions and the first parameter will be used as the value of this within the function. However, .call takes in comma-separated arguments as the next arguments while .apply takes in an array of arguments as the next argument. An easy way to remember this is C for call and comma-separated and A for apply and an array of arguments.
Explain Function.prototype.bind.
The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
In my experience, it is most useful for binding the value of this in methods of classes that you want to pass into other functions. This is frequently done in React components.
What is “use strict”;? what are the advantages and disadvantages to using it?
‘use strict’ is a statement used to enable strict mode to entire scripts or individual functions. Strict mode is a way to opt into a restricted variant of JavaScript.
Advantages:
Makes it impossible to accidentally create global variables.
Makes assignments which would otherwise silently fail to throw an exception.
Makes attempts to delete undeletable properties throw (where before the attempt would simply have no effect).
Requires that function parameter names be unique.
this is undefined in the global context.
It catches some common coding bloopers, throwing exceptions.
It disables features that are confusing or poorly thought out.
Why is it, in general, a good idea to leave the global scope of a website as-is and never touch it?
Every script has access to the global scope, and if everyone uses the global namespace to define their variables, collisions will likely occur. Use the module pattern (IIFEs) to encapsulate your variables within a local namespace.
Explain the differences on the usage of foo between function foo() {} and var foo = function() {}
The former is a function declaration while the latter is a function expression. The key difference is that function declarations have its body hoisted but the bodies of function expressions are not (they have the same hoisting behavior as variables). For more explanation on hoisting, refer to the question above on hoisting. If you try to invoke a function expression before it is defined, you will get an Uncaught TypeError: XXX is not a function error.
What are the differences between variables created using let, var or const?
Variables declared using the var keyword are scoped to the function in which they are created, or if created outside of any function, to the global object. let and const are block scoped, meaning they are only accessible within the nearest set of curly braces (function, if-else block, or for-loop).
var allows variables to be hoisted, meaning they can be referenced in code before they are declared. let and const will not allow this, instead throwing an error.
Redeclaring a variable with var will not throw an error, but ‘let’ and ‘const’ will.
let and const differ in that let allows reassigning the variable’s value while const does not.
Can you offer a use case for the new arrow => function syntax? How does this new syntax differ from other functions?
One obvious benefit of arrow functions is to simplify the syntax needed to create functions, without a need for the function keyword. The this within arrow functions is also bound to the enclosing scope which is different compared to regular functions where the this is determined by the object calling it. Lexically-scoped this is useful when invoking callbacks especially in React components.
Can you give an example of a curry function and why this syntax offers an advantage?
Currying is a pattern where a function with more than one parameter is broken into multiple functions that, when called in series, will accumulate all of the required parameters one at a time. This technique can be useful for making code written in a functional style easier to read and compose. It’s important to note that for a function to be curried, it needs to start out as one function, then broken out into a sequence of functions that each accepts one parameter.
What’s the difference between null & undefined?
Null - absence of value
Undefined - absence of definition
They both represent empty values
When you start a variable without assigning a value, it’ll automatically be undefined.
Typeof undefined is undefined
Typeof null is an object