Javascript Flashcards
What is a Closure? How/why is it used?
A closure is an inner function that has access to the outer (enclosing) function’s variables—scope chain. The closure has three scope chains: it has access to its own scope (variables defined between its curly brackets), it has access to the outer function’s variables, and it has access to the global variables
Functions such as greet that use (ie. capture) such variables (ie. free variables) are called closures.
We can use closures to pass down arguments to helper functions without explicitly listing them as arguments.
function isPalindrome(string) { function reverse() { return string.split('').reverse().join(''); }
return string === reverse();
}
Private State
Another major use of closures is to create private states. For example:
function Counter() { let count = 1;
return () => count++;
}
let counter = new Counter(); console.log(counter()); // => 1 console.log(counter()); // => 2 counter.count; // undefined By closing over (or capturing) the count variable, each Counter function has private, mutable state that cannot be accessed externally.
Compare that implementation against this one:
function Counter () { this._count = 0; }
Counter.prototype.fire = function () {
this._count += 1;
return this._count;
}
let counter = new Counter();
counter.fire(); // 1
counter.fire(); // 2
counter._count // 2
counter._count = 0 // 0 (this works);
One advantage of the closure way is that the count is truly private. In the first example, there is no way any method beside the closure itself can access the count state. In the second example, a foolish user might set counter._count inadvertently.
Free variables can be modified by closures. Consider this function:
function sum(nums) { let count = 0;
function addNum(num) { count += num; }
for (let i = 0; i < nums.length; i++){ addNum(nums[i]); }
return count;
}
sum([1, 3, 5]) // => 9
What is the keyword ‘this’ in JavaScript? How is it used? How is it related to binding?
To access the object, a method can use the this keyword.
The value of this is the object “before dot”, the one used to call the method.
“this” is not bound
In JavaScript, “this” keyword behaves unlike most other programming languages. First, it can be used in any function.
The value of this is evaluated during the run-time. And it can be anything.
In JavaScript this is “free”, its value is evaluated at call-time and does not depend on where the method was declared, but rather on what’s the object “before the dot”.
The concept of run-time evaluated this has both pluses and minuses. On the one hand, a function can be reused for different objects. On the other hand, greater flexibility opens a place for mistakes.
First, know that all functions in JavaScript have properties, just as objects have properties. And when a function executes, it gets the ‘this’ property—a variable with the value of the object that invokes the function where ‘this’ is used.
The ‘this’ reference ALWAYS refers to (and holds the value of) an object—a singular object—and it is usually used inside a function or a method, although it can be used outside a function in the global scope. Note that when we use strict mode, this holds the value of undefined in global functions and in anonymous functions that are not bound to any object.
this is used inside a function (let’s say function A) and it contains the value of the object that invokes function A. We need this to access methods and properties of the object that invokes function A, especially since we don’t always know the name of the invoking object, and sometimes there is no name to use to refer to the invoking object. Indeed, this is really just a shortcut reference for the “antecedent object”—the invoking object.
Ruminate on this basic example illustrating the use of this in JavaScript
If you understand this one principle of JavaScript’s this, you will understand the “this” keyword with clarity: this is not assigned a value until an object invokes the function where this is defined. Let’s call the function where this is defined the “this Function.”
Even though it appears this refers to the object where it is defined, it is not until an object invokes the this Function that this is actually assigned a value. And the value it is assigned is based exclusively on the object that invokes the this Function. this has the value of the invoking object in most circumstances. However, there are a few scenarios where this does not have the value of the invoking object. I touch on those scenarios later.
As an object method
When a function is called as a method of an object, its this is set to the object the method is called on.
In arrow functions, this retains the value of the enclosing lexical context’s this. In global code, it will be set to the global object:
To pass the value of ‘this’ from one context to another, use call, or apply:
ECMAScript 5 introduced Function.prototype.bind. Calling f.bind(someObject) creates a new function with the same body and scope as f, but where this occurs in the original function, in the new function it is permanently bound to the first argument of bind, regardless of how the function is being used.
What is Callback Hell?
callback-hell is an obsolete frontend-programming problem that can be easily solved using recursion. the basic problem is that most i/o in frontend-programming (and backend if using nodejs) is asynchronous, and the naive way to try and make them run sequentially requires multiple-levels of nested async callbacks (this is a textbook example of a recursion problem).
In JavaScript, what is NaN and what is its type? How can you test if a value is equal to NaN?
NaN is a property of the global object.
The initial value of NaN is Not-A-Number — the same as the value of Number.NaN. In modern browsers, NaN is a non-configurable, non-writable property. Even when this is not the case, avoid overriding it.
It is rather rare to use NaN in a program. It is the returned value when Math functions fail (Math.sqrt(-1)) or when a function trying to parse a number fails (parseInt(“blabla”)).
Testing against NaN
NaN compares unequal (via ==, !=, ===, and !==) to any other value – including to another NaN value. Use Number.isNaN() or isNaN() to most clearly determine whether a value is NaN. Or perform a self-comparison: NaN, and only NaN, will compare unequal to itself.
What is hoisting in JavaScript? Give an example of how it might be used.
Hoisting is JavaScript’s default behavior of moving declarations to the top.
JavaScript Declarations are Hoisted
In JavaScript, a variable can be declared after it has been used.
In other words; a variable can be used before it has been declared.
Variables are partially hoisted. var declarations are hoisted but not its assignments.
let and const are not hoisted.
In JavaScript, declarations are hoisted by default. This means that variable and function declarations are put into memory at compile time. Therefore, it is actually possible, on execution, to call a declared function or variable before it is defined. For instance, the following will properly call the function sayHello.
What is scope?
Scope refers to the execution context. It defines the accessibility of variables and functions in the code.
Global Scope is the outermost scope. Variables declared outside a function are in the global scope and can be accessed in any other scope. In a browser, the window object is the global scope.
Local Scope is a scope nested inside another function scope. Variables declared in a local scope are accessible within this scope as well as in any inner scopes.
The scope of a method is the set of variables that are available for use within the method. The scope of a function includes:
the function’s arguments;
any local variables declared inside the function;
any variables that were already declared when the function was defined.
Consider this example:
function sayHelloNTimes(name, n) { function greet() { console.log( `Hi, ${name}!`); }
for (let i = 0; i < n; i++) { greet(); } }
sayHelloNTimes(“Bob”, 3); // logs ‘Hi, Bob!’ x3
sayHelloNTimes(“Sally”, 6); // logs ‘Hi, Sally!’ x6
In the example above, the variable name is referenced by greet, even though it was never declared within greet. This is possible because a nested function’s scope includes variables declared in the scope where the function was nested.
What is the difference between apply, call, and bind
All of these three methods are used to attach this into function and the difference is in the function invocation.
.call() invokes the function immediately and requires you to pass in arguments as a list (one by one).
.apply() invokes the function immediately and allows you to pass in arguments as an array.
.call() and .apply() are mostly equivalent and are used to borrow a method from an object. Choosing which one to use depends on which one is easier to pass the arguments in.
the difference between call and apply:
Both can be called on functions, which they run in the context of the first argument. In call the subsequent arguments are passed in to the function as they are, while apply expects the second argument to be an array that it unpacks as arguments for the called function.
Bind is a bit different. It returns a new function. Call and Apply execute the current function immediately.
.bind() returns a new function, with a certain context and parameters. It is usually used when you want a function to be called later with a certain context.
Bind is great for a lot of things. We can use it to curry functions like in the above example. We can take a simple hello function and turn it into a helloJon or helloKelly. We can also use it for events like onClick where we don’t know when they’ll be fired but we know what context we want them to have.
ind is a method you can call on JS functions. Other methods defined on Function objects live in Function.prototype.
bind works just like the closure we made, in which cat#ageOneYear is called method style on the cat object. cat.ageOneYear.bind(cat) returns a closure that will still be called function-style, but which calls cat.ageOneYear method-style inside of it.
Note that you can bind functions to any scope, not just this:
What is global scope?
JavaScript has global scope, represented by the ‘window’ object in the browser and the ‘global’ object in Node.js. Adding attributes to these objects makes them available throughout a program.
function theBest() { window.realMVP = 'you'; }
theBest(); // initializes realMVP on the global scope
window.realMVP; // ‘you’
function whoDaBest() { return realMVP; // 'you' }
whoDaBest(); // ‘you’
While useful on occasion, global variables are usually best avoided, as they give too much code access to their values, increasing the likelihood of bugs.
What is “Use Strict”
A common mistake new JS developers commit is to unintentionally create global variables. This happens if you declare a variable without the var, let, or const keywords anywhere in your code, and can lead to strange behavior. Consider:
window.local; // undefined
function subroutine(){ local = 'oops'; }
subroutine();
window.local // ‘oops’;
Thankfully, modern JS runtimes support strict mode, which prohibits variable declaration without var, let, or const.
“use strict”;
window.local; // undefined
function subRoutine(){ local = 'oops'; }
subRoutine(); // ReferenceError: ‘local’ is not defined
Note: “use strict” does not work in the Node CLI or the Dev Tools console.
Some of its benefits are:
Makes debugging easier — Code errors that would otherwise have been ignored will now generate errors, such as assigning to non-writable global or property. Prevents accidental global variables — Assigning a value to an undeclared variable will now throw an error. Prevents invalid use of delete — Attempts to delete variables, functions and undeletable properties will now throw an error. Prevents duplicate property names or parameter values — Duplicated named property in an object or argument in a function will now throw an error. (This is no longer the case in ES6) Makes eval() safer — Variables and functions declared inside an eval() statement are not created in the surrounding scope. “Secures” JavaScript eliminating this coercion — Referencing a this value of null or undefined is not coerced to the global object. This means that in browsers it’s no longer possible to reference the window object using this inside a function.
What is the difference between initializing and declaring a variable?
Declaring a variable reserves a name and some space in memory for a variable of the specified type, but doesn’t give it a value. Initializing gives the variable a value. Depending on how you’re going to use the variable, you can declare it without initializing it and then initialize it later, or declare and initialize at the same time. For examp
Describle Prototype and __proto__ in JS.
Every function has the “prototype” property even if we don’t supply it.
The default “prototype” is an object with the only property constructor that points back to the function itself.
undefined vs null
undefined means a variable has been declared but has not yet been assigned a value. On the other hand, null is an assignment value. It can be assigned to a variable as a representation of no value. Also, undefined and null are two distinct types: undefined is a type itself (undefined) while null is an object.
discuss Prototype and inheritance
Prototype is one of the most confusing concepts in JavaScript and one of the reason for that is because there are two different contexts in which the word prototype is used.
Prototype relationship
Each object has a prototype object, from which it inherits all of its prototype’s properties.
.__proto__ is a non-standard mechanism (available in ES6) for retrieving the prototype of an object (). It points to the object’s “parent” — the object’s prototype.
All normal objects also inherit a .constructor property that points to the constructor of the object. Whenever an object is created from a constructor function, the .__proto__ property links that object to the .prototype property of the constructor function used to create it.
() Object.getPrototypeOf()is the standard ES5 function for retrieving the prototype of an object.
Prototype property
Every function has a .prototype property.
It references to an object used to attach properties that will be inherited by objects further down the prototype chain. This object contains, by default, a .constructor property that points to the original constructor function.
Every object created with a constructor function inherits a constructor property that points back to that function.
Like class Dog inheriting from class Animal
We need to make sure the the Dog proto points to the Animal prototype and not the Object prototype..
What is console.table?
If the data type is that of an object, .table will log out the results in table form.
How would we use JS to scrape data from a site?
1) Get DOM elements off page (we have to be on the page to do so)
2) Use document.querySelector(‘.thing’)
3) Then it depends on whats next
- if its with links, do category.querySelectorAll(‘a’) «_space;tag. We will get a NodeList (not array)
4) take the category query (using Array.from OR […category.querySelector(‘a)
Deconstruct arrays
if there are, say, split values, if we declare a variable encased in []’s with multiple variables, we can extract the individual values, rather place the values directly into the respective variables in the array. When the enclosed variables are returned or logged individually
how to use reduce to tally n objects
create a counter obj within reduce. the oj is the acc and the item is el and the starting value is {}
What is propertyName?
The propertyName property returns the name of the CSS property associated with the transition, when a transitionevent occurs.
This property is read-only.
What variable declaration does a non-declared variable take by default?
Var
Discuss difference between const let an var
Const cannot be reassigned, but the properties can be changed (in an object or its array values).
Neither let or const can be hoisted.
Closures: What is IIFE and what is a good example of when/how to use it?
An immediately-invoked function expression (or IIFE, pronounced “iffy”) is a JavaScript programming language idiom which produces a lexical scope using JavaScript’s function scoping.
An IIFE is a function expression that is called immediately after you define it. It is usually used when you want to create a new variable scope.
The (surrounding parenthesis) prevents from treating it as a function declaration.
The final parenthesis() are executing the function expression.
On IIFE you are calling the function exactly when you are defining it.
Incorrect: const arr = [10, 12, 15, 21]; for (var i = 0; i < arr.length; i++) { setTimeout(function() { console.log(`The value ${arr[i]} is at index: ${i}`); }, (i+1) * 1000); }
“The value undefined is at index: 4”. This happens because each function executed within the loop will be executed after the whole loop has completed, referencing to the last value stored in i, which was 4.
This problem can be solved by using IIFE, which creates a unique scope for each iteration and storing each value within its scope. const arr = [10, 12, 15, 21]; for (var i = 0; i < arr.length; i++) { (function(j) { setTimeout(function() { console.log(`The value ${arr[j]} is at index: ${j}`); }, j * 1000); })(i) }
Or
Another solution would be declaring the i variable with let, which creates the same result. const arr = [10, 12, 15, 21]; for (let i = 0; i < arr.length; i++) { setTimeout(function() { console.log(`The value ${arr[i]} is at index: ${i}`); }, (i) * 1000); }
var result = []; for (var i=0; i < 5; i++) { result.push( function() { return i } ); } console.log( result[1]() ); // 5 console.log( result[3]() ); // 5 result = []; for (var i=0; i < 5; i++) { (function () { var j = i; // copy current value of i result.push( function() { return j } ); })(); } console.log( result[1]() ); // 1 console.log( result[3]() ); // 3
Using IIFE:
Enables you to attach private data to a function.
Creates fresh environments.
Avoids polluting the global namespace.