本文详细介绍了JS面试题中涉及的基础知识,包括变量与数据类型、运算符与表达式、流程控制语句等内容。此外,文章还深入讲解了函数与作用域、对象与原型、DOM操作与事件处理以及常见的JS错误与调试技巧。通过这些内容,读者可以全面了解和准备JS面试题。
JS基础知识面试题
变量与数据类型
JavaScript 中的变量是用于存储数据的容器。变量可以分为原始类型和引用类型。原始类型包括 number
、string
、boolean
、undefined
、null
和 symbol
,引用类型包括 object
、function
、array
、date
等。
变量声明与赋值
let num = 10; // number类型
let str = "Hello World"; // string类型
let isTrue = true; // boolean类型
let undefinedVar; // undefined类型
let nullVar = null; // null类型
let symbolVar = Symbol('mySymbol'); // symbol类型
let obj = {}; // object类型
let arr = []; // array类型
let func = function() {}; // function类型
原始类型和引用类型
原始类型直接存储数据,而引用类型存储指向对象的指针。例如:
let num = 10; // number类型
let obj = {}; // object类型
运算符与表达式
JavaScript 中的运算符可以分为算术运算符、比较运算符、逻辑运算符、位运算符、赋值运算符和条件运算符。
算术运算符
let x = 10;
let y = 20;
console.log(x + y); // 30
console.log(x - y); // -10
console.log(x * y); // 200
console.log(x / y); // 0.5
console.log(x % y); // 10
比较运算符
let a = 10;
let b = 20;
console.log(a == b); // false
console.log(a === b); // false
console.log(a != b); // true
console.log(a !== b); // true
console.log(a < b); // true
console.log(a > b); // false
console.log(a <= b); // true
console.log(a >= b); // false
逻辑运算符
let a = true;
let b = false;
console.log(a && b); // false
console.log(a || b); // true
console.log(!a); // false
console.log(!b); // true
条件运算符
let a = true;
let b = false;
let result = a ? 'True' : 'False';
console.log(result); // True
位运算符
let a = 10; // 1010 in binary
let b = 2; // 0010 in binary
console.log(a & b); // 2 (0010)
console.log(a | b); // 10 (1010)
console.log(a ^ b); // 8 (1000)
console.log(~a); // -11 (11111111111111111111111111110101 in binary, which is -11 in decimal)
console.log(a << 1); // 20 (10100 in binary)
console.log(a >> 1); // 5 (00000000000000000000000000000101 in binary)
赋值运算符
let a = 10;
a += 5; // 15
a -= 5; // 10
a *= 2; // 20
a /= 2; // 10
a %= 2; // 0
流程控制语句
JavaScript 中的流程控制语句包括 if
、switch
、for
、while
和 do...while
。
if 语句
let age = 18;
if (age >= 18) {
console.log('成年人');
} else {
console.log('未成年人');
}
switch 语句
let color = 'red';
switch (color) {
case 'red':
console.log('红色');
break;
case 'blue':
console.log('蓝色');
break;
default:
console.log('其他颜色');
}
for 循环
for (let i = 0; i < 5; i++) {
console.log(i);
}
while 循环
let i = 0;
while (i < 5) {
console.log(i);
i++;
}
do...while 循环
let i = 0;
do {
console.log(i);
i++;
} while (i < 5);
break 和 continue
for (let i = 0; i < 10; i++) {
if (i === 5) {
break;
}
console.log(i);
}
for (let i = 0; i < 10; i++) {
if (i % 2 === 0) {
continue;
}
console.log(i);
}
函数与作用域面试题
函数定义与调用
函数在 JavaScript 中是第一类对象(first-class object),可以像其他对象一样被赋值给变量,作为参数传递给函数,或者作为函数的返回值。
函数定义
function greet(name) {
return `你好, ${name}`;
}
console.log(greet('世界')); // 你好, 世界
函数表达式
let greet = function(name) {
return `你好, ${name}`;
};
console.log(greet('世界')); // 你好, 世界
箭头函数
let greet = (name) => `你好, ${name}`;
console.log(greet('世界')); // 你好, 世界
作用域与变量提升
JavaScript 的作用域分为全局作用域和函数作用域。变量提升是指函数内部声明的变量会被提升到函数的顶部。
变量提升
console.log(a); // undefined
var a = 10;
console.log(a); // 10
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 20;
console.log(b); // 20
console.log(c); // ReferenceError: Cannot access 'c' before initialization
const c = 30;
console.log(c); // 30
闭包与立即调用函数表达式
闭包是指一个函数能够记住并访问它的词法作用域,即使这个函数的执行已经离开了它的原始作用域。
闭包
function createCounter() {
let count = 0;
return function() {
count++;
return count;
};
}
let counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
立即调用函数表达式(IIFE)
(function() {
console.log('IIFE 被调用了');
})();
arguments 和 rest parameters
function sum(...args) {
return args.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3)); // 6
apply 和 call
function greet(greeting, name) {
return `${greeting}, ${name}`;
}
console.log(greet.call({}, 'Hello', 'World')); // Hello, World
console.log(greet.apply({}, ['Hello', 'World'])); // Hello, World
对象与原型面试题
对象的创建与属性操作
JavaScript 中的对象可以使用字面量或构造函数的方式创建。
对象字面量
let person = {
name: '张三',
age: 30,
sayHello: function() {
return `你好, 我叫 ${this.name}, 我 ${this.age} 岁了`;
}
};
console.log(person.name); // 张三
console.log(person.age); // 30
console.log(person.sayHello()); // 你好, 我叫 张三, 我 30 岁了
构造函数
function Person(name, age) {
this.name = name;
this.age = age;
this.sayHello = function() {
return `你好, 我叫 ${this.name}, 我 ${this.age} 岁了`;
};
}
let person = new Person('张三', 30);
console.log(person.name); // 张三
console.log(person.age); // 30
console.log(person.sayHello()); // 你好, 我叫 张三, 我 30 岁了
原型与继承
每个函数都有一个原型属性(prototype
),原型对象是所有实例共享的方法和属性。
原型继承
function Animal() {}
Animal.prototype.eat = function() {
return '吃东西';
};
function Cat() {}
Cat.prototype = new Animal();
Cat.prototype.meow = function() {
return '喵喵喵';
};
let cat = new Cat();
console.log(cat.eat()); // 吃东西
console.log(cat.meow()); // 喵喵喵
原型链
function Animal() {}
Animal.prototype.eat = function() {
return '吃东西';
};
function Cat() {}
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.meow = function() {
return '喵喵喵';
};
let cat = new Cat();
console.log(cat.eat()); // 吃东西
console.log(cat.meow()); // 喵喵喵
构造函数与实例化
构造函数用于创建具有特定属性和方法的对象实例。
构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function() {
return `你好, 我叫 ${this.name}, 我 ${this.age} 岁了`;
};
let person = new Person('张三', 30);
console.log(person.name); // 张三
console.log(person.age); // 30
console.log(person.sayHello()); // 你好, 我叫 张三, 我 30 岁了
this 关键字
在方法调用和构造函数中,this
关键字的使用有所不同。
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function() {
return `你好, 我叫 ${this.name}, 我 ${this.age} 岁了`;
};
let person = new Person('张三', 30);
console.log(person.sayHello()); // 你好, 我叫 张三, 我 30 岁了
DOM操作与事件面试题
DOM元素的获取与操作
DOM(Document Object Model)是 HTML 和 XML 文档的结构化表示形式。通过 DOM,可以动态地访问和修改文档的内容和结构。
获取元素
let element = document.getElementById('myElement');
console.log(element); // HTML 元素
修改元素
let element = document.getElementById('myElement');
element.innerHTML = '新的内容';
console.log(element.innerHTML); // 新的内容
事件处理与事件冒泡
事件处理是指为 DOM 元素添加事件监听器,以响应用户操作。事件冒泡是指事件在 DOM 树中从最具体的元素向最不具体的元素传播。
事件监听
let button = document.getElementById('myButton');
button.addEventListener('click', function() {
console.log('按钮被点击了');
});
事件冒泡
<div id="outer" style="background-color: red;">
<div id="inner" style="background-color: blue;"></div>
</div>
let outer = document.getElementById('outer');
let inner = document.getElementById('inner');
outer.addEventListener('click', function() {
console.log('outer clicked');
});
inner.addEventListener('click', function() {
console.log('inner clicked');
});
// 点击 inner 会触发 inner 和 outer 的 click 事件
动态生成元素
let container = document.getElementById('container');
let newElement = document.createElement('div');
newElement.innerHTML = '新元素';
container.appendChild(newElement);
事件委托
<div id="container">
<div class="item" data-index="1">Item 1</div>
<div class="item" data-index="2">Item 2</div>
</div>
let container = document.getElementById('container');
container.addEventListener('click', function(event) {
let target = event.target;
if (target.classList.contains('item')) {
console.log(`Clicked item: ${target.getAttribute('data-index')}`);
}
});
JS常见错误与调试面试题
常见的JavaScript错误类型
JavaScript 中常见的错误类型包括:
SyntaxError
:语法错误ReferenceError
:引用错误TypeError
:类型错误RangeError
:范围错误URIError
:URI 解析错误EvalError
:eval 解析错误(已废弃)AggregateError
:聚合错误(ES2021 新增)
示例
console.log(undefinedVar); // ReferenceError: undefinedVar is not defined
console.log(someFunction()); // TypeError: someFunction is not a function
console.log(Math.pow(2, 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)); // RangeError: Maximum call stack size exceeded
调试工具的使用
JavaScript 中常用的调试工具包括浏览器内置的开发者工具(如 Chrome DevTools)和一些第三方库(如 console.log
)。
使用 Chrome DevTools
- 打开 Chrome 浏览器,按 F12 或右键点击页面选择“检查”。
- 切换到“源代码”标签,找到需要调试的文件。
- 设置断点,单击代码行号处,出现断点标志。
- 运行代码,触发断点时会暂停执行,可以查看变量值、调用栈等信息。
使用 console.log
let num = 10;
console.log(num); // 10
使用断点调试
function calculateSum(a, b) {
return a + b;
}
function testCalculation() {
let result = calculateSum(10, 20);
console.log(result);
}
// 设置断点
testCalculation();
代码优化与性能提升
代码优化可以包括减少 DOM 操作、使用缓存、避免全局变量、优化循环等。
减少 DOM 操作
let element = document.getElementById('myElement');
element.innerHTML = '新的内容';
使用缓存
let cachedData = null;
function getData() {
if (cachedData) {
return cachedData;
} else {
// 耗时操作
cachedData = '数据';
return cachedData;
}
}
避免全局变量
function a() {
let localVar = '局部变量';
console.log(localVar); // 局部变量
}
优化循环
let arr = [];
for (let i = 0; i < 1000000000; i++) {
arr.push(i);
}
console.log(arr.length); // 1000000000
JS面试题实战演练
面试题范例
常见的 JS 面试题包括变量类型、函数作用域、DOM 操作、事件处理等。
变量类型
let num = 10; // number
let str = 'Hello World'; // string
let bool = true; // boolean
let undef; // undefined
let nullVar = null; // null
let symbolVar = Symbol('mySymbol'); // symbol
let obj = {}; // object
let arr = []; // array
let func = function() {}; // function
函数作用域
function outer() {
let outerVar = '外层变量';
function inner() {
let innerVar = '内层变量';
console.log(outerVar); // 外层变量
}
inner();
}
outer();
DOM 操作
let button = document.getElementById('myButton');
button.innerHTML = '新按钮';
事件处理
let button = document.getElementById('myButton');
button.addEventListener('click', function() {
console.log('按钮被点击了');
});
面试经验分享
面试时,不仅要展示自己的技术能力,还需要展示自己的问题解决能力、学习能力和团队合作能力。在面试之前,最好准备一些常见的面试题,并通过实践加深理解。
推荐学习网站
MooC 提供了大量的在线课程和实战项目,非常适合初学者和进阶者学习。
问题解答与技巧总结
在面试中,遇到问题时不要紧张,尽量冷静分析问题,从基本概念入手,逐步推导出答案。另外,面试官可能会故意设置一些陷阱题,所以要保持清醒的头脑。
常见问题
- 如何区分
==
和===
? - 什么情况下会触发事件冒泡?
- 什么是闭包?
- 如何避免全局变量污染?
技巧总结
- 深入理解 JavaScript 的基本语法和概念。
- 熟练掌握常用的调试工具和方法。
- 注重实践,多写代码,多调试。
- 面试时保持冷静,不要紧张。
通过以上内容,希望你能对 JS 面试题有一个全面的了解,并能够在实际面试中表现出色。祝你面试成功!
共同学习,写下你的评论
评论加载中...
作者其他优质文章