This JavaScript skills test guide is for recruiters and engineering managers hiring frontend, full-stack or Node.js developers. A useful JavaScript assessment checks reasoning about the language, async code and the browser, not memorized trivia. Here you'll find what to measure by level, 11 sample questions with what a good answer covers, a comparison of test formats and a scoring rubric. The questions don't overlap with our JavaScript interview questions.
What a JavaScript skills test should measure
For a Node.js backend role, swap the browser row for server topics and see the Node.js skills test. For framework roles, add the React or Angular test after this one.
Sample JavaScript test questions
Each question shows the level and format it suits. Choose five to seven, and include at least one debugging question.
1. What does [10, 9, 1].sort() return, and how do you sort numbers correctly?
Junior, reasoning
What good looks like: it returns [1, 10, 9]. Without a compare function, sort converts elements to strings and compares them as text. Pass (a, b) => a - b for ascending numbers. A good answer notes that sort changes the array in place and returns that same array.
2. Why does ["1", "2", "3"].map(parseInt) return [1, NaN, NaN]?
Junior, reasoning
What good looks like: map calls its callback with the element, the index and the array, so parseInt receives the index as its radix. parseInt("1", 0) treats 0 as "use the default" and returns 1. Radix 1 is invalid, so parseInt("2", 1) is NaN, and "3" isn't a binary digit, so parseInt("3", 2) is NaN. Use map(Number) or map(s => parseInt(s, 10)).
3. Show two ways to give an object private state.
Junior to mid, concept
What good looks like: a closure: function makeCounter() { let count = 0; return { next: () => ++count }; }, where nothing outside can reach count. Or a class private field such as #count, which the language enforces (touching it from outside the class is a SyntaxError). An underscore prefix is only a naming convention.
4. if (isAllowed(user)) always passes, even for blocked users. isAllowed is an async function. Why?
Junior, debugging
What good looks like: an async function always returns a Promise, and every Promise object is truthy. The caller needs await isAllowed(user) inside an async function. Strong candidates mention that TypeScript with the typescript-eslint rule no-misused-promises catches this.
5. A list has 2,000 rows, each with its own click listener. What would you change?
Mid, practical
What good looks like: use event delegation: one listener on the container, with event.target.closest("li") or a data attribute to find the row. It means fewer listeners, and rows added later work without extra wiring. A strong answer notes that some events, like focus, don't bubble (use focusin), and that clickable rows should be real buttons or links for keyboard users.
6. Should a cache keyed by user-supplied strings be a Map or a plain object?
Mid, concept
What good looks like: a Map. On a plain object, keys like "__proto__", "constructor" or "toString" collide with Object.prototype, and assigning obj["__proto__"] changes the prototype instead of storing a value. A Map accepts any key type, keeps insertion order, has size and is built for frequent adds and deletes. If an object is required, Object.create(null) removes the prototype.
7. How do you make your own object work with for...of and the spread operator?
Mid, practical
What good looks like: implement [Symbol.iterator], a method that returns an iterator whose next() gives { value, done }. The simplest version is a generator method, *[Symbol.iterator]() { yield ... }. Then for...of, spread, Array.from and array destructuring all work.
8. Does Object.freeze make an object immutable?
Mid, concept
What good looks like: only shallowly. Top-level properties can't be added, removed or changed, but a nested object or array inside is still mutable. In strict mode (including ES modules and classes) a write to a frozen property throws a TypeError, while in sloppy scripts it fails silently. Deep immutability needs a recursive freeze or a data structure built for it.
9. When do you reach for a WeakMap?
Mid to senior, concept
What good looks like: to attach data to objects you don't own, such as DOM nodes or library objects, without keeping them alive. When a key object is garbage collected, its entry goes with it. Keys must be objects (or non-registered symbols), and a WeakMap can't be iterated and has no size, by design. A plain Map keyed by DOM nodes keeps removed nodes in memory.
10. A CSV import freezes the page for 4 seconds while it parses. What are your options?
Senior, practical scenario
What good looks like: the parse runs on the main thread, which blocks input and rendering. Move it into a Web Worker and send results back with postMessage (transfer an ArrayBuffer instead of copying it), or split the work into chunks and yield to the browser between them. Confirm the fix with long tasks in the Performance panel.
11. Upload 100 files with no more than 5 in flight at once. Sketch the approach.
Senior, practical
What good looks like: start 5 workers that each take the next file from a shared queue, await its upload, and loop until the queue is empty, then await Promise.all(workers). Record failures per file instead of aborting the batch, and support cancel with an AbortController. A strong candidate explains why Promise.all(files.map(upload)) starts all 100 at once.
Test formats compared
If your test is unproctored, plan for AI-assisted answers. Our guide on how to detect AI interview cheating covers practical checks, and a short live follow-up on the candidate's own code is one of the best.
Scoring rubric
Running a JavaScript test with NTRVSTA
JavaScript is part of NTRVSTA's exam library. The live AI interviewer adapts in real time: when a candidate explains the parseInt trap with confidence, it moves on to async control or main-thread performance, and when they stall, it steps down or offers a hint. It follows up on reasoning, so a lucky guess on an output question doesn't score like a real explanation. For senior full-stack roles, add a system-design question on the interactive whiteboard.
Your team gets a score breakdown (technical skills, English proficiency, communication), video snippets and a shareable candidate report. Use our JavaScript interview questions for the next round, and compare code-execution platforms in the best coding assessment tools.
Questions
How long should a JavaScript skills test be?
Thirty to 45 minutes is enough for a first round. Keep any take-home to a few hours, and don't ask candidates to build a full app from scratch.
Are trick questions like [] + {} worth asking?
Rarely. Pure coercion puzzles reward memorization. Questions like the parseInt one are better because the candidate has to reason about how a real API is called, which is a skill they use every day.
What should a junior JavaScript test leave out?
Skip memory profiling, worker threads and build tooling. Focus on core language behavior, simple async code, DOM events and reading an error message, then use follow-ups to see how they learn.
See how an adaptive JavaScript screen works in practice. Book a 20-minute demo, or run a sample interview.




