github加星 star 艾米莉 2026 前端面试核心:JavaScript 基础篇(精炼版)

39 阅读4分钟

掌握 JavaScript 基础是前端工程师的必备素养,不仅是日常开发的核心支撑,更是向中高级岗位进阶的关键基石。以下梳理了面试高频考察点,结合核心原理与实战案例,助力高效备战面试。

Taimili 艾米莉 ( 一款专业的 GitHub star 管理和github 加星涨星工具taimili.com )

艾米莉 是一款优雅便捷的 GitHub star 管理和github 加星涨星工具,基于 PHP & javascript 构建, 能对github 得 star fork follow watch 管理和提升,最适合github 的深度用户

WX20251021-210346@2x.png

一、数据类型与内存机制

1. 基本数据类型

包含 StringNumberBooleanNullUndefined、ES6 新增的 Symbol(唯一值)、ES2020 新增的 BigInt(大整数)。

  • 存储位置:栈内存(Stack)
  • 核心特性:变量直接持有值,赋值操作是值的复制,修改新变量不影响原变量。

2. 引用数据类型

Object 为基础,涵盖普通对象、ArrayFunctionDate 等。

  • 存储机制:对象实体存于堆内存(Heap),变量仅持有指向堆内存的引用地址(引用存于栈内存)
  • 核心特性:赋值操作是引用的复制,多个变量可能指向同一对象,修改任一变量的属性会影响所有关联变量。

3. 经典面试案例

javascript

运行

// 基本类型赋值:值复制,互不影响
let a = 10;
let b = a;
b = 20;
console.log(a); // 输出:10

// 引用类型赋值:引用复制,指向同一对象
let obj1 = { name: 'Mickey' };
let obj2 = obj1;
obj2.name = 'Donald';
console.log(obj1.name); // 输出:Donald

4. 类型判断方法

方法适用场景局限性
typeof快速判断基本类型1. typeof null 返回 object(历史遗留);2. 无法区分对象子类型(如 Array、Date)
instanceof判断对象是否为构造函数实例基于原型链查找,Array 实例同时属于 Object

javascript

运行

console.log(typeof []); // "object"(无法识别数组)
console.log([1,2,3] instanceof Array); // true(正确识别数组)

二、变量声明:var、let 与 const(ES6 必考点)

三者核心差异是面试高频题,需精准掌握作用域、提升机制等关键特性:

特性varletconst
作用域函数作用域块级作用域({} 包裹)块级作用域({} 包裹)
变量提升存在(仅声明提升)无(存在暂时性死区 TDZ)无(存在暂时性死区 TDZ)
重复声明允许不允许不允许
重新赋值允许允许不允许(引用不可变)

关键考点解析

  • 暂时性死区(TDZ):let/const 声明前访问变量会抛出 ReferenceError,避免变量提前使用
  • const 的 "不变性":仅保证引用地址不变,对象 / 数组的内部属性可修改

javascript

运行

const person = { age: 30 };
person.age = 31; // 允许,修改内部属性
// person = {}; // 报错,禁止修改引用地址

三、运算符(重点掌握短路特性)

1. 核心运算符分类

  • 算术运算符:+-*/%(取模)、**(ES7 幂运算)
  • 比较运算符:==(类型转换后比较)、===(严格相等,推荐使用)
  • 逻辑运算符:&&(与)、||(或)(均支持短路求值)
  • 三元运算符:condition ? 真结果 : 假结果(简洁替代简单 if-else)

2. 短路特性实战(开发高频用法)

javascript

运行

// && 短路:第一个假值直接返回,后续不执行
const userName = user && user.name; // 安全访问嵌套属性,避免报错
const result1 = 0 && console.log('不会执行'); // 输出:0

// || 短路:第一个真值直接返回,后续不执行
function greet(name) {
  name = name || 'Guest'; // ES6前的默认参数方案
  console.log(`Welcome, ${name}`);
}
greet(); // 输出:Welcome, Guest

四、流程控制

1. 条件语句

  • if...else if...else:处理多条件判断
  • switch:单值多分支场景,需注意 break 防止穿透

javascript

运行

function getFruitColor(fruit) {
  switch (fruit) {
    case 'apple': return 'red';
    case 'banana': return 'yellow';
    default: return 'unknown';
  }
}

2. 循环语句

循环类型适用场景特点
for已知循环次数灵活控制索引
while未知循环次数,条件前置条件不满足则不执行
do...while未知循环次数,条件后置至少执行一次
for...of遍历可迭代对象(数组、字符串等)直接获取值,语法简洁

javascript

运行

const numbers = [10, 20, 30];
// for...of 遍历(推荐)
for (const num of numbers) {
  console.log(num); // 输出:10、20、30
}

五、函数(JavaScript 一等公民)

1. 三种声明方式对比

声明方式语法示例核心特性
函数声明function sum(a,b) { return a+b }存在函数提升,可在声明前调用
函数表达式const multiply = function(a,b){}遵循变量提升规则,声明前不可调用
箭头函数(ES6)const subtract = (a,b) => a-b语法简洁,this 绑定词法作用域

2. 面试高频考点:函数提升

javascript

运行

console.log(declaredSum(2,3)); // 输出:5(函数声明提升)
function declaredSum(a,b) { return a+b; }

// console.log(expressedSum(2,3)); // 报错(函数表达式无提升)
const expressedSum = function(a,b) { return a+b; };

六、对象操作

1. 核心操作方法

  • 创建:const obj = { key: 'value' }(字面量语法,推荐)

  • 属性访问:

    • 点表示法:obj.key(属性名是合法标识符时使用)
    • 方括号表示法:obj['key'](支持特殊字符、动态属性名)
  • 增删改:obj.newKey = 'newVal'(增 / 改)、delete obj.key(删)

2. 遍历技巧(避免原型链污染)

javascript

运行

const car = { make: 'Toyota', model: 'Camry', 'year-2022': true };
// for...in 遍历,仅获取自身属性
for (const key in car) {
  if (car.hasOwnProperty(key)) {
    console.log(`${key}: ${car[key]}`);
  }
}

七、数组(高频操作与方法)

1. 核心特性

  • 访问:通过索引 arr[index],索引从 0 开始
  • length:可读写属性,用于获取长度或截断数组

2. 常用方法分类(面试重点)

类型方法特点
改变原数组push/pop、unshift/shift、splice、sort直接修改原数组,需注意副作用
不改变原数组concat、slice、map、filter、find返回新数组,原数组保持不变(推荐使用)

3. 经典面试对比:map vs forEach

javascript

运行

const ids = [1, 2, 3];
// forEach:仅遍历,无返回值
ids.forEach(id => console.log(`处理ID:${id}`));

// map:映射转换,返回新数组(核心用途)
const urls = ids.map(id => `/users/${id}`);
console.log(urls); // 输出:['/users/1', '/users/2', '/users/3']

八、DOM 操作与事件模型

1. 高效 DOM 操作(性能优化考点)

大量添加节点时,使用 DocumentFragment 减少重排(reflow)和重绘(repaint):

javascript

运行

const list = document.getElementById('my-list');
const fragment = document.createDocumentFragment(); // 临时容器

// 先添加到片段(无DOM重排)
for (let i = 0; i < 1000; i++) {
  const li = document.createElement('li');
  li.textContent = `Item ${i+1}`;
  fragment.appendChild(li);
}

// 一次性插入DOM(仅1次重排)
list.appendChild(fragment);

2. 事件委托(性能优化 + 动态元素适配)

利用事件冒泡机制,将监听器绑定到父元素,统一处理子元素事件:

html

预览

<ul id="parent-list">
  <li>Item 1</li>
  <li>Item 2</li>
</ul>

javascript

运行

const parent = document.getElementById('parent-list');
parent.addEventListener('click', (e) => {
  // 精准匹配目标元素
  if (e.target.nodeName === 'LI') {
    console.log(`点击了:${e.target.textContent}`);
  }
});

九、AJAX 与本地存储

1. fetch API(主流异步请求方案)

基于 Promise,需手动处理 HTTP 错误状态码:

javascript

运行

async function fetchUserData() {
  try {
    const res = await fetch('https://api.example.com/user/1');
    if (!res.ok) throw new Error(`HTTP错误:${res.status}`); // 处理404/500等错误
    const data = await res.json(); // 解析JSON响应
    console.log(data);
  } catch (err) {
    console.error('请求失败:', err);
  }
}

2. 本地存储方案对比(面试高频)

方案生命周期存储大小与服务器通信
localStorage永久存储,手动清除约 5MB不携带,仅客户端使用
sessionStorage标签页关闭后清除约 5MB不携带,仅客户端使用
Cookie可设置过期时间(默认会话)约 4KB每次 HTTP 请求自动携带