Comprehensive JavaScript Fundamentals for Frontend Interviews

This article covers JavaScript interview questions with both questions and answers. For deeper insights, refer to my detailed blog posts (comprehensive). Each question includes links to relevant articles.

  1. Variable Declarations and Types

1.1 Differences between var, let, and const

  1. var is an ES5 feature, while let and const are ES6 additions
  2. var exhibits hoisting behavior
  3. var and let are variables that can be modified; const is a constant that cannot be changed
  4. let and const have block scope, whereas var has function scope

1.2 Data Types

Primitive types (7): Undefined, Null, Number, String, Boolean, Symbol (ES6), BigInt (ES10)

Reference types: Object including Array and Function

1.3 Primitive vs Reference Types

Primitive types reside in stack memory, with variables holding their actual values

Reference types reside in heap memory, with variables storing references (addresses)

1.4 typeof Operator Capabilities

  1. undefined, string, number, boolean, symbol, bigint (excluding null)
  2. function
  3. object (typeof null === 'object')

1.5 Methods for Type Detection

  1. typeof (except null and functions)
  2. instanceof (reference types, traverses prototype chain)
  3. toString() (any type)
  4. Array.isArray() (arrays)

1.6 Strict Equality (===) vs Abstract Equality (==)

=== performs strict comparision

== performs type coercion before comparison

100 == '100'
0 == ''
0 == false
false == ''
null == undefined

A special case for ==:

if(a == null) {}
// Equivalent to
if(a === null || a === undefined)

1.7 Truthy and Falsy Values

Truthy: values that evaluate to true when converted to boolean

Falsy: values that evaluate to false when converted to boolean

Falsy values include:

!!0 === false
!!NaN === false
!!'' === false
!!null === false
!!undefined === false
!!false === false

1.8 Explicit vs Implicit Type Conversion

Explicit conversions: parseInt, parseFloat, toString

Implicit conversions: conditional statements, logical operators, ==, string concatenation (+)

1.9 Expressions vs Statements

Expressions produce values and can be used anywhere a value is expected

a
a+b
demo(1)
x===y? 'a': 'b'

Statements perform actions

if(){}
for(){}

  1. Arrays and Strings

2.1 Implement Deep Cloning

function deepClone(obj){
	if (typeof obj !== 'object' || obj === null){
		return obj
	}
	let result = Array.isArray(obj) ? []: {}
	for (let key in obj) {
		if(obj.hasOwnProperty(key)) {
			result[key] = deepClone(obj[key])
		}
	}
	return result
}

2.2 Implement Deep Comparison

// Check if object or array
function isObject(obj) {
  return typeof obj === 'object' && obj !== null;
}

// Deep comparison
function isEqual(obj1, obj2) {
  if (!isObject(obj1) || !isObject(obj2)) {
    return obj1 === obj2;
  }
  if (obj1 === obj2) {
    return true;
  }
  const obj1Keys = Object.keys(obj1);
  const obj2Keys = Object.keys(obj2);
  if (obj1Keys.length !== obj2Keys.length) {
    return false;
  }
  for (let key in obj1) {
    const res = isEqual(obj1[key], obj2[key]);
    if (!res) {
      return false;
    }
  }
  return true;
}

2.3 Pure Functions in Array API

Pure functions do not mutate the original array and return a new one:

  • concat, map, filter, slice

Impure functions modify the original array:

  • push, pop, shift, unshift, forEach, somme, every, reduce

2.4 split() vs join()

split() is a string method

join() is an array method

'1-2-3'.split('-') // ['1','2','3']
['1','2','3'].join('-') // '1-2-3'

2.5 slice() vs splice()

slice() creates a copy of a portion

splice() modifies the original array

2.6 Implement String Trim

String.prototype.trim = function() {
	return this.replace(/^\s+/, '').replace(/\s+$/, '')
}

  1. Functions

3.1 Function Declaration vs Expression

Function declaration

function fn(a, b) {
  return a + b;
}

Function expression

let fun = function(a, b){
  return a + b;
}

3.2 What is JSON?

JSON is a data format represented as a string

Its structure resembles JS objects, making it more compatible with JS

JSON is a global object with methods like JSON.stringify and JSON.parse

3.3 Parse URL Parameters into JS Object

Traditional approach using search parameter parsing

function queryToObj() {
	const res = {}
	const search = location.search.substr(1)
	search.split('&').forEach(paramStr => {
		const arr = paramStr.split('=')
		const key = arr[0]
		const val = arr[1]
		res[key] = val
	})
	return res
}

Using URLSearchParams

function queryToObj() {
	const res = {}
	const pList = new URLSearchParams(location.search)
	pList.forEach((val, key) => {
		res[key] = val
	})
	return res
}

  1. Prototype and Prototype Chain

4.1 Prototype and Prototype Chain Explanation

Every function has an explicit prototype property

Every instance has an implicit __proto__ property

The __proto__ points to the prototype of its constructor

4.2 Class Prototype Nature

Class is an ES6 syntax defined by ECMA committee

ECMA defines syntax rules but not implementation details

4.3 Difference Between new Object() and Object.create()

  • {} equals new Object(), prototype is Object.prototype
  • Object.create(null) has no prototype
  • Object.create({...}) allows specifying prototype

4.4 Create a Simple jQuery Using Class Syntax

class jQuery {
  constructor(selector) {
    const result = document.querySelectorAll(selector);
    const length = result.length;
    for (let i = 0; i < length; i++) {
      this[i] = result[i];
    }
    this.length = length;
    this.selector = selector;
  }

  get(index) {
    return this[index];
  }

  each(fn) {
    for (let i = 0; i < this.length; i++) {
      const elem = this[i];
      fn(elem);
    }
  }
  
  on(type, fn) {
    return this.each((elem) => {
      elem.addEventListener(type, fn, false);
    });
  }
}

// Plugin
jQuery.prototype.dialog = function(info){
	console.log(info);
}

// Extension
class myjQuery extends jQuery{
	constructor(selector){
		super(selector)
	}
	addClass(className){}
	addStyle(data){}
}

  1. Scope and Closures

5.1 Scope

Scope determines where a variable is valid

JS uses lexical scoping (static scope)

Global scope, function scope, block scope

Free variibles: not defined in current scope but used, searched upward

5.2 this Binding in Different Contexts

this binding is dynamic based on execution context

const User = {
	count: 1,
	getCount: function() {
		return this.count
	}
}
console.log(User.getCount()) // 1
const func = User.getCount
console.log( func() ) // undefined

5.3 Implement bind Method

Function.prototype.myBind = function() {
	const args = Array.prototype.slice.call(arguments)  
	const t = args.shift()
	const self = this
	return function() {
		return self.apply(t, args)
	}
}

5.4 Closure

A closure occurs when a function accesses variables from its outer scope even after the outer function has finished executing

5.5 Closure Applications

Hide data, expose APIs only

function createCache() {
	const data = {}
	return {
		set: function(key, value) {
			data[key] = value
		},
		get: function(key){
			return data[key]
		}
	}
}

const cache = createCache()
cache.set('a', 100)
console.log(cache.get('a'))

  1. ES6 Features

Refer to specific articles for detailed explanations of ES6 features including:

  • Variable declarations (var, let, const)
  • Symbol usage
  • Arrow functions
  • Destructuring assignment
  • Enhanced object literals
  • Default parameters
  • Array creation methods
  • Iterator methods
  • Classes and inheritance
  • Iterators and generators
  1. Asynchronous Programming

7.1 Synchronous vs Asynchronous

Due to single-threading, asynchronous operations prevent blocking

JS shares thread with DOM rendering

7.2 Common Async Scenarios

Network requests, timeouts

7.3 Promise States

  1. pending - waits for resolution or rejection
  2. resolved - triggers subsequent then callbacks
  3. rejected - triggers subsequent catch callbacks

7.4 Promise then and catch

Promise.resolve().then(()=>{
	console.log(1)
}).catch(()=>{
	console.log(2)
}).then(()=>{
	console.log(3)
})

7.5 Implement Promise Image Loading

function loadImg(src){
	return new Promise((resolve, reject)=>{
		const img = document.createElement('img')
		img.onload = () =>{
			resolve(img)
		}
		img.onerror = () => {
			reject(new Error(`图片加载失败 ${src}`))
		}
		img.src = src
	})
}

// Usage
const url = ''
loadImg(url).then(img => {
	console.log(img.width)
	return img
}).then(img => {
	console.log(img.height)
}.catch(err => console.error(err))

7.6 async/await vs Promise

  1. async function returns a Promise
  2. await is equivalent to Promise's then
  3. try/catch can handle errors instead of catch

7.7 ByteDance Interview Code Example

async function async1() {
  console.log("async1 start");
  await async2();
  console.log("async1 end");
}

async function async2() {
  console.log("async2");
}

console.log("script start");
async1();

new Promise((resolve)=>{
	console.log('promise1');
	resolve();
}).then(()=>{
	console.log('promise2');
})

console.log("script end");

7.8 for-of Use Cases

for-of for asynchronous iteration

function muti(num) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(num * num);
    }, 1000);
  });
}

const nums = [1, 2, 3];

nums.forEach(async (i) => {
  const res = await muti(i);
  console.log(res);
});

(async function () {
  for (let i of nums) {
    const res = await muti(i);
    console.log(res);
  }
})();

  1. Event Loop

8.1 Macro Tasks vs Micro Tasks

  • Macro tasks: setTimeout, setInterval, Ajax, DOM events
  • Micro tasks: Promise, async/await

8.2 Event Loop Mechanism

Call stack, event loop, callback queue, micro task queue

8.3 Event Loop Practice

console.log('1');

setTimeout(function() {
    console.log('2');
    process.nextTick(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})

process.nextTick(function() {
    console.log('6');
})

new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})

setTimeout(function() {
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
    
    console.log('13');
    
    process.nextTick(function() {
        console.log('14');
    })
})

Output: 1 7 6 8 2 4 3 5 9 11 13 10 14 12

  1. DOM Operations

9.1 Node Selection

document.getElementById('yk')
document.getElementsByTagName('div')

document.getElementsByClassName('container')
document.querySelectorAll('p')

9.2 Attribute Manipulation

Modifies HTML attributes

const pList = document.querySelectorAll('p')
const p = pList[0]

p.getAttribute('data-name')
p.setAttribute('data-name','ykjun')
p.getAttribute('style')
p.setAttribute('style', 'font-size: 10px')

9.3 Property Manipulation

Modifies JS object properties

const pList = document.querySelectorAll('p')
const p = pList[0]
console.log(p.style.width)
p.style.width = '100px'

console.log(p.className)
p.className = 'p1'

console.log(p.nodeName)
console.log(p.nodeType)

9.4 DOM Structure Manipulation

const div1 = document.getElementById('div1')
const div2 = document.getElementById('div2')

const newP = document.createElement('p')
newP.innerHTML = 'this is new p'

div1.appendChild(newP)

const p1 = document.getElementsByTagName('p')[0]
div2.appendChild(p1)

console.log(p1.parentNode)

const div1ChildNodes = div1.childNodes
console.log('div1ChildNodes', div1ChildNodes)

const div1ChildNodesP = Array.from(div1ChildNodes).filter(child => {
	if(child.nodeType === 1) {
		return true;
	}
	return false;
}
console.log('div1ChildNodesP', div1ChildNodesP)

div1.removeChild(div1ChildNodesP[0])

9.5 DOM Performance Optimization

9.5.1 Cache DOM Queries

const pList = document.getELementsByTagName('p')
const length = pList.length
for(let i = 0; i < length; i++){
	// Cache length, only one DOM query
}

9.5.2 Batch DOM Operations

const listNode = document.getElementById('list')
const frag = document.createDocumentFragment()
for(let i = 0; i < 10; i++){
	const li = document.createElement('li')
	li.innerHTML = "Iist Item " + i
	frag.appendChild(li)
}
listNode.appendChild(frag)

  1. BOM

Navigator, Screen, Location, History

10.1 Browser Detection

const ua = navigator.userAgent
const isChorme = ua.indexOf('Chrome')
console.log(isChorme)

10.2 URL Components

Location object provides access to URL components

  1. Events

11.1 Event Binding, Bubbling, Delegation

const btn = document.getElementById('btn1')
btn.addEventListener('click', event => {
	console.log('clicked')
})

11.2 Universal Event Binding Function

function bindEvent(elem, type, fn){
	elem.addEventListener(type, fn)
}

const btn1 = document.getElementById('btn1')
bindEvent(btn1,  'click', event => {
	console.log(event.target)
	event.preventDefault()
	alert('clicked')
})

11.3 Event Bubbling Process

Events propagate up through the DOM tree

11.4 Infinite Scroll Image Click Listener

Use event delegation with event.target and matches

  1. AJAX

12.1 Custom AJAX Implementation

function ajax(url) {
	const p = new Promise((resolve, reject) => {
		const xhr = new XMLHttpRequest()
		xhr.open('GET', url, true)
		xhr.onreadystatechange = function () {
			if(xhr.readyState === 4) {
				if(xhr.status === 200) {
					resolve(
						JSON.parse(xhr.responseText)
					)
				} else if (xhr.status === 404) {
					reject(new Error('404 not found'))
				}
			}
		}
		xhr.send(null)
	})
	return p
}

// Usage
const url = '/data/test.json'
ajax(url)
.then(res => console.log(res))
.catch(err => console.log(err))

12.2 Cross-Origin Solutions

  • Images, CSS, JS bypass same-origin policy
  • JSONP, CORS, proxy
  1. Browser Storage

13.1 Cookies

Used for browser-server communication

Max size 4KB

13.2 localStorage and sessionStorage

HTML5 storage, max 5MB

Simple API: setItem, getItem

  1. Page Loading

14.1 Resource Types

HTML, media files, JavaScript, CSS

14.2 Complete Load Process

  1. Resource acquisition
  2. DOM tree generation
  3. CSSOM construction
  4. Render tree assembly
  5. Page rendering

14.3 window.onload vs DOMContentLoaded

onload waits for all resources

DOMContentLoaded waits for DOM ready

14.4 Repaint vs Reflow

Repaint: style changes without geometry impact

Reflow: geometry changes requiring recalculation

  1. Performance Optimization

15.1 Common Optimization Strategies

  1. Memory caching, reduce CPU load
  2. Reduce resource size, network calls
  3. Use faster networks (CDN)

15.2 Caching

Static resources with hash suffixes

15.3 SSR

Server-side rendering improves initial load

15.4 Lazy Loading

Load high-resolution images only when needed

15.5 Throttling and Debouncing

Control frequency of function calls

  1. Frontend Security

16.1 XSS

Prevent cross-site scripting attacks

16.2 CSRF

Prevent cross-site request forgery

  1. Algorithm Practice

Sorting algorithms, LeetCode problems categorized by topics

Tags: javascript frontend Interview ES6 Prototype

Posted on Sat, 05 Sep 2026 16:21:35 +0000 by bawla