JavaScript interview questions

I was perusing my list o' RSS feeds this evening — Yes, I'm one of those people who still read RSS — and happened upon a list of JavaScript interview questions posted by James Padolsey. This reminded me that I had a few questions tucked away from when I was contacted by a Meebo recruiter a few years ago.

I didn't apply for the job, because I was working at the (now defunct) startup Viewzi, and I didn't want to uproot from Dallas and move to California. Just for kicks, I asked the recruiter if it'd be okay if I went ahead and tried my hand at their code questions anyway. After which, the recruiter replied:

You aced the puzzlers, well done! Are you sure you don't want to be considered for our JavaScript / Front-End Developer position? If you ever have the itch to move to CA, be sure to let me know!

Since a few years have elapsed since then, I am hoping that it is kosher for me to share these questions, along with the answers I provided…


1. When does div.setAttribute('###') not equal div.###?

Answer:

When you're trying to set an element's class attribute, IE has issues. Therefore, it's better to use .className instead of .setAttribute(). There is also an issue with .setAttribute() and style in IE, so .style should be used.

// Don't do this:
el.setAttribute('class', 'foobar');

// Do this instead:
el.className = 'foobar';

// Don't do this:
el.setAttribute('style', 'color: #000');

// Do this instead:
el.style.color = '#000';

2. What's the difference between these two statements:

var x = 3;

x = 3;

Answer:

The first puts the variable in the scope of whatever function it was defined. The second places the variable in global scope. It can potentially cause collision with other variables with the same name. Therefore, the keyword var should always be used when defining variables, and an anonymous function should be used as a closure if need be, encapsulating multiple functions which can share access to the same set of variables. That makes sure the variables stay sandboxed, accessible only by those functions which need them.


3. What's the difference between:

!!(obj1 && obj2);

obj1 && obj2;

Answer:

The first returns a "real" boolean value, because you first negate what is inside the parenthesis, but then immediately negate it again. So, it's like saying something is "not not" truth-y, making it true. The second example simply checks for the existence of the obj1 and obj2, but might not necessarily return a "real" boolean value, instead returning something that is either truth-y or false-y. This can be problematic, because false-y can be the number 0, or an empty string, etc. Simple existence can be truth-y. A "real" boolean will only be true or false.


4. Write a one-line piece of JavaScript code that concatenates all strings passed into a function.

(Formatting added for readability.)

function concatenate() {
return String.prototype.concat.apply('', arguments);
}

More on that here…

sitepen.com/blog/2008/05/09/string-performance-an-analysis


5. What do these two examples have in common?

Short Answer:

Both create potential memory leaks, especially in Internet Explorer.

Example 1:

var obj = document.getElementById('adiv');

document.getElementById('adiv').ptr = obj;

Long Answer:

This is bad practice, because you first assign a DOM element to a variable, but then you assign that same element to a (nonexistent) property of the element itself. This creates a sort of circular logic loop, and will negatively impact performance.

Example 2:

function assignClick() {
var el = document.createElement('div');

function handleClick() {
el.innerHTML = 'clicked!';
}

el.attachEvent('onclick', handleClick);
}

Long Answer:

This example will only work in Internet Explorer, because it employs the proprietary .attachEvent() method. Granted, .innerHTML is also proprietary (now a standard), but unlike .attachEvent(), .innerHTML is widely supported in all modern browsers. To make this example more cross-browser friendly, the W3C standard .addEventListener() should attempted first, and if it does not exist, then try .attachEvent() as a fallback.


This article has been translated into the following languages: