DEV Community

Emma Bostian ✨
Emma Bostian ✨

Posted on

What’s your favorite JS interview question?

What’s your favorite interview question to ask a candidate?

Discussion (44)

Collapse
ufocoder profile image
Sergey Ivanov

What will output these example? Why?

for (var i=0; i < 10; i++){
    setTimeout(function(){
        console.log(i);
    }, 1000);
}
Enter fullscreen mode Exit fullscreen mode

How to fix it to output numbers from 0 to 9?

Collapse
bharath_bheemireddy profile image
Bharath_Bheemireddy

Using let you will get output numbers from 0 to 9.

Collapse
jakebman profile image
jakebman

Feel free to run it and prove me wrong, but I believe that it prints 10 ten times, at 1 second intervals.

It's due to binding on the variable I, not the value of I when you create the lambda.

You need to introduce a local variable in the loop body to fix it.

Thread Thread
akashkava profile image
Akash Kava

You are wrong, if you use for(let i instead of for(var i it will print 0 to 9 correctly. jsfiddle.net/uh86qx1v/1/

Thread Thread
hiattzhao profile image
Hiatt

Can you explain why that happens? I'm new to ES6 and learned that let has block scope. When used in the for loop, in conjunction with setTimeOut set to 1000, you would think the console.log would run every 1000 ms for each console.log. But this doesn't happen. When I tried it, the sequence of console.logs appear all at once after 1000 ms. Why does that happen? Is it because setTimeOut, when called 10 times, gets pushed to the stack, then after 1000 ms the stack does its thing and all 10 calls are executed simultaneously?

If you take out the setTimeOut and just do console.log within the for (var i loop you get the correct result as well.

Thread Thread
jakebman profile image
jakebman

Yup, you're correct. The callbacks are registered very close to each other - they're all queued up to run at basically the same time.

Thread Thread
jakebman profile image
jakebman

Akash - this is the local variable I was trying to describe: jsfiddle.net/e7gyc5ts/1/ (I needed an IIFE to solve a problem that is better solved by let)

Thread Thread
ufocoder profile image
Sergey Ivanov
Thread Thread
bharath_bheemireddy profile image
Bharath_Bheemireddy
Collapse
sarathsnair profile image
Sarath S Nair • Edited on
  • Using let

for(let i=0; i<10; i++) {
setTimeout(()=>console.log(i),i*500);
};

  • Using bind

for(var i=0; i<10;i++) {
setTimeout(console.log.bind(null,i), i*100);
};

  • Or you can use IIFE

for(var i=0; i<10; i++) {
(function(x){
setTimeout(()=> console.log(x), x*100)
})(i);
};

Collapse
kenbellows profile image
Ken Bellows

On the bind example, heads up that in some older browsers you need to pass console as the first argument to any console.<method>.bind(). Not that this is a particularly real-world thing to do, but it's bitten me a few times when trying to debug a promise chain in an older browser; I always love to do promise.then(console.log), but in old browsers this breaks until you do promise.then(console.log.bind(console)).

Collapse
genocideaon profile image
Pranat

It is an excellent question to test how much you understand JS.

Collapse
fervero profile image
Maciej Bójko • Edited on

Fun trivia: setTimeout can have more than two arguments. After the callback function, and the duration, you can pass args for the callback, as well. Instead of working around setTimeout, use setTimeout.

for (var i = 0; i < 10; i++) {
   setTimeout(console.log, 100*i, i); 
}

(Although I don't even write the for loop, like, ever. It's all map, filter, reduce etc. So I'd rewrite it into something like this:

new Array(10)
   .fill(0)
   .map((x, i) => i)
   .forEach(x => setTimeout(console.log, 100*x, x))
Collapse
raslanove profile image
raslanove

for (var i=0; i<10; i++) {
setTimeout(function() { console.log(i++ - 10); }, 1000);
}

Collapse
vsrikanth49 profile image
Srikanth

for (var i = 0; i < 10; i++) {
setTimeout(
(function (i) {
console.log(i)
})(i),
1000
)
}

Collapse
cilice profile image
Alexander Plavinski

Why is this your favourite question?

Collapse
ufocoder profile image
Sergey Ivanov

Because answer on this question will discover what answerer know about:

  • Scopes
  • Closures
  • How event loop works in the browser
Collapse
vsrikanth49 profile image
Srikanth • Edited on

for (var i = 0; i < 10; i++) {
setTimeout(
(function (i) {
console.log(i)
})(i),
1000
)
}

Collapse
niorad profile image
Antonio Radovcic

For candidates with a clear focus on a specific technology/library/framework/… I always ask "In which case would you not use that?".

Or a similar version of that question.

Like "For which kind of project would Angular be a bad architectural choice?".

Because one size never fits all and it's always a good discussion-starter.

I don't ask weird syntax-questions. It's just rude. It doesn't tell me anything at all about the person. It's exploiting their nervousness for no gain. I want to know if they will make the right calls, and produce working, readable and tested solutions. You know, the stuff that is not one google-search away.

Collapse
ky1e_s profile image
Kyle Stephens • Edited on

Solid approach.

Remember, interviewing is a two-way street. It's just as much about you assessing a prospective employer/boss as it is them assessing you.

If an interviewer tries to "catch you out" with some arbitrary, illegible code or tries to belittle you because you don't know answers to some esoteric problem then it says more about them and their approaches to work than it does about your knowledge/abilities.

Collapse
niorad profile image
Antonio Radovcic

Most def, it's more a conversation-starter, without a "right" answer. If they can argue their claim, perfect.

I think I could argue why React should always be used, sometimes be used, and never be used :-)

Thread Thread
ky1e_s profile image
Kyle Stephens

Absolutely. Evidence about ways of thinking/approaching a problem are much more revealing about a candidate than their ability to interpret obtuse code like a compiler.

Collapse
akashkava profile image
Akash Kava • Edited on

What will be output of

(() => console.log(this)).bind("done")()

var fx = (() => console.log(this));
fx.call("done");

Try in chrome, you will not see "done"

(() => console.log(arguments))("a");
Collapse
themindfuldev profile image
Tiago Romero Garcia • Edited on

Great question! I believe this is because arrow functions can't be bound and also don't have arguments, for that we need to use regular function definitions:

(function() { console.log(this) }).bind("done")();

var fx = (function() { console.log(this) });
fx.call("done");

(function() { console.log(arguments) })("a");
Collapse
misterwhat profile image
Jonas Winzen

You can't bind anything to an arrow functions this. But you can bind arguments to them. ie:

((arg) => console.log(arg)).bind(null, "done")()

would work.

Thread Thread
themindfuldev profile image
Tiago Romero Garcia

Oh nice! Thanks for explaining that.

Collapse
cilice profile image
Alexander Plavinski

I always like to ask which project the candidate is most proud of, like what's their "darling" and why is that so. This always opens room to see what they care for, how can they articulate that and opens room for more questions.

Collapse
thorstenhirsch profile image
Thorsten Hirsch

Yay, that's also my favourite interview question... and I hope to be asked that question, too, when I'm the candidate.

Collapse
ben profile image
Ben Halpern

I'd ask what the candidate used for build tooling in personal projects and any previous team projects. I think the answer to this question would tell me a lot about how they approached their work and would lead to an insightful conversation.

Collapse
buzzfair profile image
Guin White • Edited on

I'm new to JS, and I'm pretty clear on why this logs 10 to the console, but I'm not understanding why it logs it 10 times. Can someone please explain this to a noob?

PS - apologies for reactivating an older thread, but this code actually came up in another context, and when I searched I found this discussion. Thanks for understanding.

Collapse
tnacioustyson profile image
Tyson Williams

Any that I know and get right. 😅

Collapse
lexlohr profile image
Alex Lohr

What's your favorite addition to ECMAscript?

Collapse
not_jffrydsr profile image
@nobody

What's difference between this


kung.prototype.fu = function() { juli.do_the_thing(); 
}

and this


class kung {

  fu() { 
   do_the_thing(juli);
    }
 }
Collapse
pawail profile image
Pawail A. Qaisar

I know this might sound a bit ridiculous, but...

'When was the first time you touched a computer?'

'And when was the first time a computer touched you?'

No pun intended! :)

Collapse
johnpaulada profile image
John Paul Ada

Create a non-brute force autocomplete function in JavaScript. 😎

Collapse
pinotattari profile image
Riccardo Bernardini

I am not a JS expert, but... TAB == 0 ?!? 😲

Collapse
eavichay profile image
Avichay Eyal

Implement Promises using function generators only.

Collapse
kevinoca profile image
Kevin Oca

Beside your question, Can i ask where it becomes usefull to use generators? i know about them but haven't used yet in production code.

-Performance optimizations maybe?

Collapse
misterwhat profile image
Jonas Winzen

They are useful wherever you want to suspend and handle control (and optionally a value) back to the caller. When the caller is done doing its stuff, he can decide to give you back control (also optionally with a value). Your function continues where it has stopped before.

A prominent use case are CSP (communicating sequencial processes) style concurrency models, where multiple processes read and write to and from a shared channel. Processes can block and wait until some specified message type is observed on the channel. On the other hand, processes can write to the channel, without caring if there is another process that would make use of the message (you could write error log messages to the channel but only display them in dev mode and otherwise send them to a remote endpoint for further processing them in e.g. Kibana).

The great advantage of this model is the loose coupling that allows you to simply swap out or replace parts of your application depending on your needs.