JavaScript的知识体系可以分为多个模块进行复习,以下是一个可能的划分及细分知识点举例:
一. 基础语法模块
-
变量声明:var、let、const的区别与作用域
var x = 1; // 可重新赋值,函数作用域 let y = 2; // 不可重新声明,块级作用域 const z = 3; // 常量,不可重新赋值或声明 if (true) { var a = 'inside'; let b = 'also inside'; console.log(a); // 输出 "inside" console.log(b); // 输出 "also inside" } console.log(a); // 输出 "inside" console.log(b); // 报错(b未定义)
-
数据类型:基本类型(Number, String, Boolean, Null, Undefined, Symbol)和引用类型(Object)
面试中关于数据类型的问题通常会包括但不限于以下几个方面:
1.基本数据类型(Primitive Types):
- 在JavaScript中,基础数据类型包括:
string
、number
、bigint
、boolean
、null
、undefined
、symbol
。 - 例如:
let str = "Hello, World!"; console.log(typeof str); // 输出 "string" let num = 42; console.log(typeof num); // 输出 "number" let bool = true; console.log(typeof bool); // 输出 "boolean" let sym = Symbol("description"); console.log(typeof sym); // 输出 "symbol"
2.引用数据类型(Reference Types):
- 主要是
object
类型及其子类型,如Array
、Function
、Date
、RegExp
等。 - 例如:
let obj = { name: "Alice" }; console.log(typeof obj); // 输出 "object" let arr = [1, 2, 3]; console.log(Array.isArray(arr)); // 输出 "true"
3.值的复制与传递:
- 基本类型复制是值的拷贝,而引用类型复制的是引用地址。
let a = 10;
let b = a; // 值复制
b = 20;
console.log(a); // 输出 10,a不受b改变的影响
let obj1 = { value: 10 };
let obj2 = obj1; // 引用复制
obj2.value = 20;
console.log(obj1.value); // 输出 20,因为obj1和obj2指向同一对象
4.类型转换:
- 显式类型转换:
Number()
,String()
,Boolean()
等函数,以及parseInt()
,parseFloat()
等。
console.log(Number('123')); // 输出 123
console.log(Boolean(0)); // 输出 false
5.隐式类型转换:
- 操作符引发的类型转换,如
+
运算符在连接字符串时对数字的操作。
console.log('1' + 2); // 输出 "12"
console.log(1 + '2'); // 输出 "12"
6.深拷贝、浅拷贝:
浅拷贝(Shallow Copy)
浅拷贝是指复制对象时,只复制对象的引用而不复制对象本身。这意味着如果原对象和拷贝对象中存在引用类型的属性(如数组、对象等),那么它们将共享这些引用类型的数据。
// 示例:浅拷贝
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = Object.assign({}, obj1);
console.log(obj2); // 输出 { a: 1, b: { c: 2 } }
obj1.b.c = 3;
console.log(obj2); // 输出 { a: 1, b: { c: 3 } } // 修改了obj1.b.c后,obj2中的b属性也被影响,因为它们指向同一个内存地址
// 或者使用解构赋值进行浅拷贝
let obj3 = { ...obj1 };
深拷贝(Deep Copy)
深拷贝则是完全复制对象及其所有嵌套的对象或数组。修改原始对象不会影响到副本,反之亦然。
// 示例:深拷贝(递归实现)
function deepCopy(obj) {
if (typeof obj !== 'object' || obj === null) {
return obj; // 如果不是对象或者null,直接返回
}
let copy;
if (Array.isArray(obj)) {
copy = []; // 数组则创建新的空数组
} else {
copy = {}; // 对象则创建新的空对象
}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
copy[key] = deepCopy(obj[key]); // 递归处理子对象或子数组
}
}
return copy;
}
let obj4 = { a: 1, b: { c: 2 } };
let obj5 = deepCopy(obj4);
console.log(obj5); // 输出 { a: 1, b: { c: 2 } }
obj4.b.c = 3;
console.log(obj5); // 输出 { a: 1, b: { c: 2 } } // 修改了obj4.b.c后,obj5中的b属性不受影响,因为它们是独立的内存空间
// 或者使用第三方库如lodash的_.cloneDeep方法
let obj6 = { a: 1, b: { c: 2 } };
let obj7 = _.cloneDeep(obj6);
在实际开发中,根据具体需求选择合适的方法进行数据复制,避免由于浅拷贝导致的数据修改异常。
- 数据类型的判断:
在JavaScript中,判断数据类型的方法主要有以下几种:
-
typeof 运算符
let value = "Hello"; console.log(typeof value); // 输出 "string" value = 42; console.log(typeof value); // 输出 "number" value = null; console.log(typeof value); // 输出 "object" (注意null的特殊性) value = true; console.log(typeof value); // 输出 "boolean" value = Symbol(); console.log(typeof value); // 输出 "symbol" (ES6新增) value = function() {}; console.log(typeof value); // 输出 "function" value = undefined; console.log(typeof value); // 输出 "undefined" // typeof 对于数组和正则表达式返回的是 "object" value = []; console.log(typeof value); // 输出 "object" value = /abc/; console.log(typeof value); // 输出 "object"
-
instanceof 关键字
let array = []; console.log(array instanceof Array); // 输出 true let date = new Date(); console.log(date instanceof Date); // 输出 true
-
Object.prototype.toString.call()
let arr = []; console.log(Object.prototype.toString.call(arr)); // 输出 "[object Array]" let func = function() {}; console.log(Object.prototype.toString.call(func)); // 输出 "[object Function]" let obj = {}; console.log(Object.prototype.toString.call(obj)); // 输出 "[object Object]"
-
constructor 属性
let str = "Hello"; console.log(str.constructor === String); // 输出 true let num = 42; console.log(num.constructor === Number); // 输出 true
-
Array.isArray()
let arr = []; console.log(Array.isArray(arr)); // 输出 true
请注意,typeof
在处理 null
类型时会返回 "object"
,这可能与预期不符,所以在实际使用中需要特别注意。而 Object.prototype.toString.call()
方法可以提供更为准确的数据类型信息,特别是在区分数组、函数、正则表达式等引用类型时。同时,对于自定义对象或复杂类型,可以配合构造函数或者类的继承关系进行类型判断。
-
特殊值的处理:
- 如NaN(非数字),它不等于任何值,包括自身。
console.log(NaN === NaN); // 输出 false
-
JavaScript中的弱类型特性:
- JavaScript如何进行动态类型检查,以及它的灵活性带来的潜在问题。
-
ES6新引入的数据类型:
- BigInt用于表示超过
Number.MAX_SAFE_INTEGER
的大整数。
let bigNum = 123456789012345678901234567890n; console.log(typeof bigNum); // 输出 "bigint"
- BigInt用于表示超过
根据具体的面试级别和职位要求,面试官可能会更深入地探讨数据类型的内存分配、性能影响、具体实现细节等问题。
- 运算符:算术运算符、比较运算符、逻辑运算符、位运算符等
- 流程控制:if…else、switch、for、while、do…while、break、continue等
二. 函数模块
-
函数声明与表达式
function add(a, b) { return a + b; } const subtract = function(x, y) { return x - y; }; const multiply = (x, y) => x * y;
-
作用域与闭包
function outer() { let innerVar = 10; function inner() { console.log(innerVar); } return inner; } const func = outer(); func(); // 输出 10
-
高阶函数与函数式编程:map、filter、reduce、forEach等数组方法应用
三. 对象与原型链模块
-
对象创建与属性访问
const obj = { name: 'Alice', age: 30 }; console.log(obj.name); // 输出 "Alice" // 属性动态添加与删除 obj.city = 'New York'; delete obj.age;
-
构造函数与原型
function Person(name) { this.name = name; } Person.prototype.sayName = function() { console.log(this.name); }; const person = new Person('Alice'); person.sayName(); // 输出 "Alice"
四. 异步编程模块
-
回调函数
setTimeout(function() { console.log('异步操作完成'); }, 1000);
-
Promise
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } delay(1000).then(() => console.log('延迟一秒后执行'));
-
async/await
async function fetchUser(id) { const response = await fetch(`https://api.example.com/users/${id}`); const data = await response.json(); return data; } (async () => { const user = await fetchUser(1); console.log(user); })();
五. DOM与BOM操作模块
-
DOM节点选择与操作
const element = document.getElementById('myElement'); element.innerHTML = 'Hello, World!';
-
事件处理
button.addEventListener('click', function(event) { console.log('Button was clicked!'); });
-
BOM对象:window、location、navigator、history等
六. ES6+新特性模块
-
解构赋值
const [firstName, lastName] = ['Alice', 'Smith']; console.log(firstName); // 输出 "Alice"
-
模板字符串
const name = 'Alice'; console.log(`Hello, ${name}!`); // 输出 "Hello, Alice!"
-
Class与继承
class Animal { constructor(name) { this.name = name; } speak() { console.log(`${this.name} makes a sound.`); } } class Dog extends Animal { speak() { console.log(`${this.name} barks.`); } } const dog = new Dog('Rufus'); dog.speak(); // 输出 "Rufus barks."
-
模块化导入导出
// 导出 export const PI = 3.14; // 导入 import { PI } from './math';
-
迭代器与生成器
function* countDown(n) { while (n > 0) { yield n--; } } const gen = countDown(5); console.log(gen.next().value); // 输出 4
七. 高级主题模块
- 性能优化:懒加载、资源压缩、CSS Sprites、缓存策略等
- 错误处理:try…catch、Error对象、全局异常捕获
- 设计模式:单例模式、工厂模式、观察者模式在JavaScript中的应用
- 前端框架:React、Vue、Angular等框架的基本概念和用法
- 测试:单元测试(如Jest)、集成测试、E2E测试等基础知识
以上只是大致的一个分类和示例,实际复习时可以根据个人需求进一步细化每个模块下的知识点。