Answering FEE Interview Questions - Part 4: JS the 3th

HWY36 should be on the bucket list of every motorcyclist in the whole wide world. This is a great day-long route!
HWY36 should be on the bucket list of every motorcyclist in the whole wide world. This is a great day-long route!

Previously: part 4 - js #1part 4 - js #2

The number of JS questions in the Front-end Interview Questions repo is pretty extensive, so I’m going to break them up into several blorg posts. This is part 3 of my JS answers.

Q. Difference between document load event and document DOMContentLoaded event? Why would you use something like the load event? Does this event have disadvantages? Do you know any alternatives, and why would you use those?

I'm combining a couple questions in this answer since there's some overlap.

DOMContentLoaded

This event fires when the DOM from the inintial HTML has finished loading and parsing. It does not wait for external resources to load. This is a good event to hook to when you will be modifying the page's content, but you need to be sure that any structure you might need has already loaded.

load

This window event fires when all resources for the page have loaded, including subframes, images and style sheets. Because of its dependency on additional requests and possibly external servers, it can take significantly longer to fire than DOMContentLoaded.

In the interest of speed and taking care of our users though, this is an ideal event to listen to to load our ads. They're not relevant to our content and usually just irritate anyone reading, so it's best to wait until the important pieces of our site have loaded and only then loading ads.

Q. What is the difference between == and ===?

The difference is that == does type conversion, attempting to make both sides of the equality check the same type before doing a value comparison, whereas === checks both type and value.


Q. Explain the same-origin policy with regards to JavaScript.

The same-origin policy exists to prevent cross-site scripting attacks. The origin of a page is defined by its protocol (http vs https), port, and domain name. Here's a table showing some comparisons from MDN:

The table gives examples of origin comparisons to the URL http://store.example.com/dir/page.html:
URL Outcome Reason
http://store.example.com/dir2/other.html Success  
http://store.example.com/dir/inner/another.html Success  
https://store.example.com/secure.html Failure Different protocol
http://store.example.com:81/dir/etc.html Failure Different port
http://news.example.com/dir/other.html Failure Different host

In two of the failures above (not when attempting cross-protocol), we would not be able to use XMLHttpRequests to those URLs without first setting document.domain = 'example.com' on both the requesting page and the destination URL.

Q. Make this work: duplicate([1,2,3,4,5]); // [1,2,3,4,5,1,2,3,4,5]

This is a pretty easy one. There seems to be one subtle detail though, in that we want to include the brackets around our string.

1
2
3
4
5
function duplicate( arr ) {
  return arr.concat( arr );
}
// use JSON.stringify() to include the brackets for the literal
console.log( JSON.stringify( duplicate([1,2,3,4,5]) ) );


Q. Why is it called a Ternary operator, what does the word "Ternary" indicate?

Ternerary indicates 3, binary 2, and unary 1. In a ternary operator, there are three parts to the operation:

conditional logic ? evals to true : evals to false
1 2 3
conditional logic ? evals to true : evals to false

It's a nice concise way to perform if...then...else statements, particularly useful when doing variable assignments:

1
2
3
4
function isEven( num ) {
  var result = num % 2 ? false : true;
  return result;
}
Q. What is "use strict";? what are the advantages and disadvantages to using it?

Introduced in ECMAScript 5, "use strict"; enables strict mode in your code. It can be used either at the function level, or globally at the top of an included script file. It's intended to get rid of the some of the assumed behavior in JS by throwing more errors where the engine previously ignored bad behavior or made assumptions about intent.

John Resig has an oft-cited write up from several years ago that details strict mode quite well, but in a nutshell:

  • foo = 1 will throw an error; requires var statement or explicitly making it a property of window. E.g., window.foo = 1;
  • { foo: true, foo: false } will result in an error because you're redefining a property
  • using "eval" as a property, variable, or function name will throw an error; additionally, no new variables can be defined via eval()
  • .caller and .callee will throw an error
  • with() {} statements are completely deprecated

Strict mode is mostly beneficial to our development, as it forces developers to be more explicit in their intentions. The only major downside to it is that if it's turned on globally, there are likely many libraries and legacy code that will throw errors where they used to hum along just fine.

Q. Create a for loop that iterates up to 100 while outputting "fizz" at multiples of 3, "buzz" at multiples of 5 and "fizzbuzz" at multiples of 3 and 5

This is an old standard:

1
2
3
4
5
6
7
8
9
10
11
(function() {
  'use strict';
  var output;

  for ( var x = 1; x <= 100; x++ ) {
    output = x + ': ';
    output += ( x % 3  ) ? '' : 'fizz';
    output += ( x % 5  ) ? '' : 'buzz';
    console.log( output );
  }
})();


Q. Why is it, in general, a good idea to leave the global scope of a website as-is and never touch it?

If you've read through more of my answers to these JS questions, you may have noticed that I'm big on removing ambiguity from code. This means using shunning languages that rely on significant indentation, using curly braces, semicolons, 'use strict';, and explicitly defining variables where they're used. One of the original sins of JS is that it assumes global (window) scope, meaning that if I just randomly typed blurt = 10; in my code somewhere, that variable will become global, polluting the namespace and confusing the poor bastard maintaining it after me. Additionally, if that maintainer were also a fan of onomatopoeia and used the variable blurt, he would clobber mine, leading to some silly and easily-prevented bugs in our code.

Fortunately, strict mode has made the omission of var throw errors now, so that mistake should eventually vanish from most code. There're still the significant issues of maintenance, context, and collisions. With so many libraries in use now, it's important that they (and we as consumers) do not rely upon globals for our code. When using the module pattern, we should instead be passing in as parameters any potential global library variables we'll need in our module. This gives a future reader of our code important context down the road when maintenance becomes important.

Q. Explain what a single page app is and how to make one SEO-friendly.
What it is

It's a helluva lot of JS, usually relying upon a library like Ember or Angular. It has state, models, routing (and bookmarking!), and history. It distributes some of the processing onus on the client instead of the server, but usually relies upon a well-written RESTful server API (which is good for everyone involved for longevity). As far as the UX goes, pages are comprised of components and templates and requests happen asynchronously, so full-page refreshes are not required, making the page responsive and snappy for the user.

SEO and Single-Page Apps

For cross-browser friendliness, URLs in webapps have traditionally been managed using the hash: /posts/#post-title, /posts/#another-post-title. Now that older browsers that didn't fully support HTML5's history management have been deprecated though, apps can finally use history.pushState() to provide the world with pretty URLs and perhaps become easier for search engines to crawl.

Beyond the address bar, there are other issues with crawlers. Because the payload when navigating a webapp is typically just JSON, a search engine may not know that a page has completed loading and may only index a small amount of content. There are some solutions to this though, as many frameworks now support server-side rendering.

Q. What is the extent of your experience with Promises and/or their polyfills? What are the pros and cons of using Promises instead of callbacks?

My experience is admittedly limited. I was introduced to promises back in 2013 at LinkedIn, when we were working on a major rewrite of the profile page. The rewrite included JS templating, tons of async calls to fetch individual sections, edit-in-place, I think drag-and-drop as well. As promises weren't yet a part of vanilla JS, we were using jQuery's implementation, which as I understand it wasn't entirely true to what is now the standard.

Because of my limited experience with them, I can't strongly argue in favor of or oppose their use. I read this great introduction to them, and while I was happy to be following along, as the example progressed and got more complex, I found that just reading the code, let alone understanding its flow, became pretty tiresome. The major benefit of promises is that they're intended to save us from "callback hell," where we may be cascading async functionality through a series of nested callbacks. This sucks, but chaining a bunch of .then() and .catch() statements together also makes for a pretty confusing flow.

At the bottom of that intro to promises, there is another introduction, this time to generators, a new feature in ES6. Now this looks like something I could get behind. The rewritten code to fetch all the content on his sample page using the generator functions makes a lot more sense to me. I look forward to getting more familiar with these and async functions.

Q. What are some of the advantages/disadvantages of writing JavaScript code in a language that compiles to JavaScript?
Cons, as I see them (having never used a transpiler):
  1. I know how to write JS (ok, well, I sort of know it). Why do I need to learn another language to write a language I already know?
  2. I should be using a linter already that integrates with my IDE of choice, so I can avoid silly mistakes like omitting a var statement, and presumably that linter can be configured to adhere to your organization's coding patterns.
  3. I don't find the syntax of CoffeeScript to be any easier to understand than vanilla JS.
  4. I don't want to have to install yet another freaking developer tool to handle compilation.
  5. I think significant indentation is one of the dumbest concepts ever conceived in a programming language.
  6. I ALREADY KNOW JS! (being terrible at it doesn't usually make me understand its syntax less)
Pros?

I have never used a language that compiles into JS, so I don't know!

Q. What tools and techniques do you use debugging JavaScript code?

Chrome's devtools, Firebug (when it was a thing), Safari's dev console, debugger statements, console.log().

Firebug was my first foray into JS debugging, and it's probably the tool that led me to actually liking JS development. Microsoft's attempts at debugging tools were so riddled with bugs themselves that they were no more useful than putting a bunch of alert()s in your code. Chrome has since supplanted my love of Mozilla products.

Posted under: JS