JavaScript Topics

The following are important JavaScript topics and commonly used in Front-End Developer interviews. This page is where I explore each JavaScript topic and link to helpful resources.

Testing

Double checking your code. Ideally performed before you write what you need to write.

Behavior Testing

Browser testing. See how the website updates when you click on a link or other sorts of interactions.

Unit Testing

Testing very small pieces of code.

Libraries for Testing

Mocha

The actual testing framework. Provides the actual commands. Written by TJ Holowaychuk.

Chai

Provides the actual expect statements. Testing is all about writing statements: here is what I have, here is what I expect.

Event Loop

JavaScript environments (the browser, node, etc.) have a mechanism for handling executing multiple chunks of a program over time.

JavaScript has the ability to tell the hosting environment to suspend execution for now, but whenever a request has some data (a “callback”), call this function back.

The scheduling for the callback function to be executed is the event loop. The environment inserts the function into the event loop to be executed after a response comes back.

What is it exactly?

The event loop looks at the call stack and the task queue and if there isn't anything in the stack pushes the first thing in the task queue.

Picture and array. If that array has a length of greater than 0 (something in it), then remove the first element from the array and return it. Try executing that element, and if an exception is thrown report the error.

If there are a ton of events in the event loop, then the callback gets in line and waits. Even if that callback is from a setTimeout(…) (which explains why they aren’t always accurate!).

Call Stack

The call stack is the execution path of the JavaScript engine. It is a data structure that records where in the program we are. Calling functions pushes them to the stack and returning them (or coming to their end) pops them off.

Task Queue

The task queue is the list of tasks to be entered into the event loop when it is done completing (like after you get a response in an AJAX request).

“Don't block the event loop”

Don't put slow code on the stack because it blocks what the browser needs to do (render).

Resources

Philip Roberts Presentation

“use strict”;

This is the expression used to opt in to Strict Mode in JavaScript. It forces you to use version ES5.

Can be used for entire scripts or individual functions.

It helps an author make fewer errors by detecting what could lead to breakages.

It:

Strict mode will keep any undeclared variables from being declared in the global scope.

Strict mode changes the value of this to undefined instead of the Global or Window object.

Disadvantages

None.
There is the surprise of not being able to use things that you thought you could.

Single Page App & SEO

A SPA is a web app that loads a single HTML page and then dynamically updates the page using AJAX and HTML5. The asynchronous JavaScript requests (AJAX) remove page reloads and HTML5 provides us with the ability to adjust the browser’s history api so that users can still utilize the back and forward buttons.

The HTML5 History API allows us to manipulate the contents of the history stack. We can use the history.pushState() method to add and modify history entries.

There are also many frameworks available to construct SPAs more easily.

SEO

Historically, AJAX applications have been difficult for search engines to process because AJAX content is produced dynamically by the browser and thus not visible to crawlers.

Crawlers are not able to see any content that is created dynamically. As a result, the most modern applications are also the ones that are often the least searchable.

To make the crawler see what a user sees, the server needs to give a crawler an HTML snapshot, the result of executing the JavaScript on your page.

Allow the site owner's own web server to return to the crawler the HTML – created from static content pieces as well as by executing JavaScript – for the application's pages. This is what is called HTML snapshot.

Parallel Universe

One way to fix problems of AJAX and SEO is to allow users of JavaScript-enabled browsers to see content that is created dynamically, and users of non-JavaScript-enabled browsers (as well as crawlers) to see content that is static and created offline.

The idea here is progressive enhancement where the user and crawler bot are both happy. Here is an example from Google:

When creating your links, format them so they'll offer a static link as well as calling a JavaScript function. That way you'll have the AJAX functionality for JavaScript users, while non-JavaScript users can ignore the script and follow the link. For example:

<a href="ajax.htm?foo=32" onClick="navigate('ajax.html#foo=32'); return false">foo 32</a>

Note that search engines understand URL parameters (?foo=32) but often ignore fragments (#foo=32).

Making AJAX Crawl-able

  1. Utilize an AJAX crawling scheme. The application must use a specific syntax in the AJAX URLs (let's call them “pretty URLs;” you'll see why in the following sections). The search engine crawler will temporarily modify these “pretty URLs” into “ugly URLs” and request those from your server.
  2. This request of an “ugly URL” indicates to the server that it should not return the regular web page it would give to a browser, but instead an HTML snapshot.
  3. When the crawler has obtained the content for the modified ugly URL, it indexes its content, then displays the original pretty URL in the search results.

Resources

.call() and .apply()

Every function in JavaScript has the .call() and .apply() methods. Both take an object to use for the this binding and then invoke the function with that this. They also both take parameters needed for the function.

Example

function peter() {
  console.log( this.age );
}

var someObj = {
  age: 31
};

peter.call( obj ); // 31

I am invoking peter with explicit binding by peter.call() to force peters this to be someObj.

Differences

The .call method is usually used when you have a set of values already as variables that you would like to pass as the second parameter.

The .apply method only takes additional parameters in the form of an array. The value here is seen often with splitting the arguments object from another function.

Event Delegation

Event Delegation is the ability to attach an event listener to a parent element which will fire for all descendants matching some selector.

When an event fires, it ‘bubbles’ up through the DOM, which in turn triggers each of the parent event handlers. This is called event propagation. So, if you had a click handler on a <button> somewhere in the DOM, clicking on it would fire an event that bubbles up through the DOM. Like so:

<html>
    <body>
        <p>Subscribe to our newsletter</p>
        <button type=“submit”>Sign Up</button>
    </body>
</html>

Clicking on <button> above would do this:
<button> >>> <body >>> <html> >>> document

Event Delegation is using this event propagation to handle events from a higher level in the DOM. It means we can attach a single event listener for current elements and elements that may appear in the future. An event listener that watches for action on specified descendent selectors.

If we added another <button> in the <body> of the code above that required the same functionality from an event firing on it, we could simply attach an event listener to the parent (<body>) that checks for events that match some parameter.

Overall, what’s the benefit here?

The ability to attach an event listener to a parent means we could manipulate the DOM and add more descendants in the future and they would be watched over as well. If that wasn’t the case, we would have to rebind an event to the added descendants.

Also, if we were to remove a child element we would not need to unbind it (in order to avoid leaking).

Browser Detection

Sometimes you need to detect what browser is used. All of this is bad, to me, because I like to support progressive enhancement.

Example

You want to send users with an older browser to an older website with less features.

Feature Detection

Check to see if a feature exists. If it does, then you can take advantage and if it doesn’t you can have some sort of fall back.

Feature Inference

Here, you add assumption. If a browser implements a feature and another one does not, then I can write some code.

The problem here is that browsers change and implementations change, and then your code is wrong.

UA String

You can use a UA string (find one here to see what browser (and hence, features) is used.

Callbacks

Callbacks are the fundamental unit of asynchrony in JavaScript. They are the target for the event loop to “call back into” the program whenever that item in the queue is processed. Callbacks wrap up (encapsulate) the continuation of the program.

The callback function is the simplest way of “waiting” from now until later.

Many callbacks make it difficult to trace the async flow.

As JavaScript becomes more sophisticated, Promises offer a better way to deal with asynchrony. Promises offer a more sequential, synchronous way to deal with asynchrony as well as keep the control of our program.

Promises

or, composing future values

My Experience

We used promises pretty extensively in Moment App. The primary reason is to be able to control what to do with track data when it is delivered: either throw an error or load the information in some way.

How do they work?

We wrap the continuation of a program in a callback function, hand that callback to another party, and hope that the invocation of the callback does the right thing.

But we don’t want to hand that callback to another party without the ability to know when it has finished—so that we can decided what to do next.

The Promise object is used for operations that haven’t completed yet, but are expected to in the future. The resolution of a Promise can be fulfillment or rejection.

What are they?

Promises are the values returned, or not returned, by functions passed as values. They are future values.

  1. Method(s) that are sent off to get values.
  2. The Promise object has methods used to create a promise.
  3. The then() method creates another promise, which can take two arguments for success and failure.
  4. Once resolved, it is an immutable value.

Resources

YDKJS

The Ternary Operator

The JavaScript ternary operator is a “conditional operator” that works like an if…else statement.

var result = toEvaluate ? if-its-true : if-its-false;

So, the first clause results if the expression is true and if not, the second clause results.

It’s common to see the ternary operator used as an assignment.

+/- of Writing JS in Compiler

Pros

Cons

Properties and Attributes

DOM elements are objects with properties. Examples of properties are:

In JavaScript, you can access these using the Node web API.

var listItem = document.getElementById(“contact-links”);
console.log(listItem.parentNode); // <footer>…</footer>

Attributes are in the HTML document and always have an initial value. That value is always a string, not another type. Properties can be a boolean, string, number, etc.

Some properties have the same or similar names to HTML element attributes, and many of them get their initial values from the HTML element’s attributes. For example, href gets its initial value from the href attribute.

A good way of thinking about properties is that they are representations of attributes in the DOM tree. For example, the attribute class has a property called className.

Properties can change. A good example is changing the value of a checkbox or input text into a <input>. Changing the default value set on an <input> changes the DOM element’s value property, but not the HTML attribute, which would stay the same.

When to use each?

Properties tend to be more consistently implemented across browsers, so it is best to only utilize attributes when there is no property related to it. Examples of this include data-.

Resources

Anonymous Functions

I try to avoid anonymous functions, but they are common when a function is a function expression. When a function expression is assigned to a variable you commonly see an anonymous function. Or functions used as event handler.

AJAX

Asynchronous JavaScript and XML

AJAX is a technique that uses a combination of XMLHttpRequest objects and JavaScript to exchange data with a server to update parts of a web page. This means the page doesn’t need to be reloaded.

XMLHttpRequest

AJAX makes heavy use of the XMLHttpRequest object, which is an API that provides an easy way to get data from a URL. There are different XHTTP methods like send() to send a request to the server, open() to initialize a request, and setRequestHeader() to set the value of an HTTP request header.

AJAX Drawbacks

Probably the most obvious drawback to dynamically creating page content is that the back and refresh buttons won’t work.

Another drawback is error handling since you need to tell the user if something has gone wrong.

Also, if a server that you are accessing for your site doesn’t allow cross-origin resource sharing and JSONP, then you are limited in accessing other servers. You are not allowed to make AJAX requests to a web page on a different server as perceived by the browser.

JSONP

Which leads us to JSONP! “JSON with Padding” is a method used to bypass cross-domain policies in web browsers.

AJAX calls cannot be made to reference cross domain servers without specific permissions. The same-origin policy restricts how a document or script loaded from one origin can interact with another, it is a security mechanism imposed by browsers.

JSONP requests are not sent using the XMLHttpRequest API, but instead use a <script> tag with source set to the target URL, which is added to the DOM <head>.

JSONP requests contain a callback parameter so the server knows the name of the function to wrap the response around. A JSON response is just an object.

load and DOMContentLoaded

The DOMContentLoaded event fires when the HTML document is loaded and parsed, and the DOM tree is completely constructed.

var someText = document.createTextNode(“Some text”);
var someSection = document.getElementById(“section”);

window.addEventListener(“DOMContentLoaded”, function(event) {
  someSection.appendChild(someText);
});

In this example someText will appear when the HTML document is loaded. In the below example using the load event, someText will appear after all subframes, images, stylesheets, scripts, etc have been loaded.

window.addEventListener(“load”, function(event) {
  someSection.appendChild(someText);
});

null, undefined, and “undeclared”

null and undefined are both JavaScript types.

null is a special keyword, not an identifier. It cannot be treated as a variable.

undefined is an identifier. It is a value that a declared variable can hold. The only value of undefined is undefined.

undefined hasn’t had a value. A value is missing. No value currently. An “undefined” variable is one that has been declared in the accessible scope, but currently has no other value in it.

An ”undeclared” variable is one that has not been declared in the accessible scope.

null had a value, and doesn’t anymore. An empty value. If you want to test for a null value using its type, you need a compound condition.

Example:

var peter;
var strumolo = null;

typeof peter; // “undefined”
(!strumolo && typeof strumolo === “object”); // true

Note that the typeof operator returns “object” for null

The typeof operator returns ”undefined” even for “undeclared” variables.

var peter;

typeof peter; // “undefined”
peter; // “undefined”
typeof strumolo; // “undefined”
strumolo; // ReferenceError: strumolo is not defined

load Event

The load event is best used to detect a fully-loaded page. That is everything: images, stylesheets, scripts, everything.

Obviously, what it does is kind of a disadvantage. If you want to detect page load, you probably want to use the DOMContentLoaded event instead, so you are not worrying about large images loading or big stylesheets.

Prototypal Inheritance

Summary

Let us say we have two objects: one is considered a class and one an instance of that class. In JavaScript these objects are linked via the Prototype mechanism. With this linkage, one object can delegate access to another object.

“Prototypal Inheritance” is confusing because it is actually JavaScript's prototype link mechanism and not one of class or inheritance. What it actually is:

An internal link that exists on one object which references another object.

The linkage is used when a property reference is made on one object that does not exist. The engine then goes to the linked-to object and if it isn't there continues to that object's prototype link. This is the prototype chain.

The actual mechanism of prototypal (inheritance) linkage is all about objects being linked to other objects.

Inheritance OOD to Delegation OOD

Lots more to add here...

Constructors

A JavaScript constructor is a function call with the new operator to construct a new object.

Capitalized Function Declaration

function Peter() {}

A function that is declared with a capitalized identifier, it is generally intended to be used for a constructor call or a module. The author is intending to use the function with the new operator.

Function Instantiation

var peter = Peter();

Here we have a function being invoked and assigned to the variable peter. Whatever is returned from the function is ultimately assigned to that variable, and it can be used to access properties on it.

Constructor Call

var peter = new Peter();

Functions called with the new operator in front of them are constructor calls. There is no such thing as “constructor functions”—only construction calls of functions.

Using new creates a brand new object, linked to the prototype object of the function being called, the this is bound to the new object, and return the newly constructed object.

JavaScript Templating

I’ve used templating in AngularJS where just a couple HTML partials that contain HTML, CSS, and Angular expressions and directives are viewed in a default template. To accomplish this, I’ve used the ngView directive.

== vs ===

Both == and === are equality operators. Here is the difference:

==

== checks for value equality with coercion allowed.

===

=== checks for value without allowing coercion.

Coercion

var someString = “32”;
var someNumber = 32;

someString == someNumber; // true
someString === someNumber; // false

Here, “32” becomes 32 to make the comparison. JavaScript noticed that the types did not match and so it went through an ordered series of steps to coerce “32” into 32 and then did the equality check.

Remember

If you can be certain with values use ==, if you can’t then use ===.

Resources

YDKJS

Closure

Closure occurs when a function utilizes its lexical scope from outside of that scope. For example, passing a function call to an event handler means that later, when it fires, the function is referencing its enclosing scope, which is called closure.

Basically, when you transport an inner function outside of its lexical scope, it will maintain a scope reference to where it was declared. So when it is executed, closure occurs.

Closure occurs all the time in our code.

The revealing module pattern is a good example since you have an outer enclosing function that is invoked to create a module instance with hidden inner function being returned. The inner functions have closure over the private scope of the module.

Leave the Global Scope as-is

Because adding variables to the global scope means they are accessible everywhere and can easily be overwritten.

This can lead to bugs, confusion among developers, weird names.

It is best practice to limit what is added to the Global Scope since they are things you want to have benefitted by being there—like a variable to access the innards of a module.

It’s also really easy to mess up. If you have

var someGlobalVariable = “Peter”;
function someFunction() {
  someGlobalVariable = “Strumolo”;
  console.log(someGlobalVariable);
}
someFunction(); // Strumolo
console.log(someGlobalVariable); // Strumolo

you accidentally overwrote the global variable.

Iterating over Objects and Arrays

for...in iterates over property names, for...of iterates over property values.

let arr = [3, 5, 7];
arr.foo = "hello";

for (let i in arr) {
   console.log(i); // logs "0", "1", "2", "foo"
}

for (let i of arr) {
   console.log(i); // logs "3", "5", "7"
}

Extending built-in JavaScript Objects

Not a good idea.

When you extend a native prototype, you are adding non-standard functionality to a built-in type.

Since you can just use Object.create() to create a new object with a specified prototype and properties, there is no reason to break encapsulation.

Encapsulation is the bundling of data with the methods that operate on that data.

Difference Between Host & Native Objects

A native object is one defined by the the ECMAScript specification instead of the host environment. Any object that is not native is a host object.

Object, Function, Number, String, Math, Date, and many others

A host object is anything that isn’t a native object. If the host is a browser, then window, document, XMLHttpRequest, and others.

Event Bubbling

Event bubbling or event propagation occurs when an event propagates through the ancestors of the element that the event fired on. So, when there is a handler on a parent of the event, bubbling determines which order the elements are received.

This leads to event listeners and event delegation since it means you can put an event listener on a parent element (or some ancestor) and have it watch for an event on a descendant.

Synchronous vs Asynchronous Functions

A synchronous function will run one after the other. This is common in JavaScript because it compiles our code and then executes it in the order it was compiled.

An asynchronous function is one that will run later at an unknown time. These functions are commonly seen as callback functions which execute in response to some sort of event (ajax response, clicking, a timer, etc.).

Mutable and Immutable Objects

Mutable

An object can be changed over time. Mutation attempts to erase history. Objects are mutable.

Immutable

After an object is created it can never be changed. Values are immutable.

Ways to achieve immutability

  1. Object.freeze() prevents new properties from being added to an object and existing properties from being removed or changed. Basically, a immutable version is returned.
  2. Object.seal() prevents new properties from being added and existing properties cannot be configured. However, values of present properties can still be changed (if writeable).

Pros and Cons of Immutability

Pros

Cons

Named function vs anonymous function expression

function foo() {}
and
var foo = function () {}

A function declaration will be hoisted to the top of its defined scope. The anonymous function expression will not and can only execute after the variable has been declared.

Immediately Invoked Function Expression

Explain why function foo() { }(); does not work as an IIFE

Firstly, because function is the very first thing in the statement. This means it is a function declaration and foo is just a variable in the outer enclosing scope. Plus, there is a weird () following it.

The second there is something to the left of the word function, it becomes and expression. As an expression we can effectively hide any enclosed variable or function declarations from the outside scope inside the function’s inner scope.

To make function foo() { }(); work as an IIFE, we need to make the name foo not bound to the enclosing scope, but instead bound to the inside of its own function. By placing () around the function makes it an expression. The other () at the end of the statement execute the function.

Function.prototype.bind

bind() returns a new function that is hard-coded to call the original function. It creates a new wrapper function that is hard-coded to ignore its own this binding and use the manual one provided.

.bind is similar to .call and .apply but will not invoke the function in question and simply return it to you. So, you can set the context of a function without actually invoking it.

Invoking this new function will in turn invoke the original function with the context that was specified in the .bind call.

function simpleMath(a, b){
  return this.f + a + b;
}

//bind the function to a context
var myContext = {
  f: 1
};
var boundStuff = simpleMath.bind(myContext);

// call the bound function with additional parameters
var result = boundStuff(2, 3);
console.log(result); //=> 6

Same-origin Policy

Two pages have the same origin if the protocol, port, and host are the same for both.

This policy restricts how a document or script loaded from one origin can interact with a resource from another origin. It is a security mechanism.

What’s allowed?

Since the <script> tag is not constrained by the policy, a script on a third-party domain can provide executable code that interacts with a provided callback function. This is the case with JSONP.

Debugging Tools

Developers need powerful debugging tools to quickly discover the cause of an issue and also fix it efficiently.

In the Browser

Chrome Developer Tools

Vim

Syntastic Linter

Other

JSLint

What is this all about?

In JavaScript, every single function—while it is executing—has a reference to its current execution context, which is called this. this is a binding made when a function is invoked, so what this references is determined at the function’s call-site.

this is not a reference to the function itself, nor is it a reference to the function’s lexical scope.

So, what is ‘execution context’?

Functions are called, but how are they called? That is the key to determining this. Kyle Simpson outlines 4 rules to determining this based on a function call’s call-site.

Hoisting

All declarations, both variables and functions, are processed first by JavaScript. Subsequently they are executed by the engine.

When they are processed they are moved to the top of their respective scopes, and this is called hoisting.

The order is functions first and then variables second.

document.write();

document.write() writes to a document (the web page) the content to which you pass in as the parameter.

  1. Using it after the page has loaded will change the content by overwriting the page.
  2. document.write does not work for XHTML pages.
  3. Use innerHTML instead.

Best Uses