专题 前端面试知识梳理大全

发布于:2025-07-25 ⋅ 阅读:(14) ⋅ 点赞:(0)

前端面试知识梳理大全

🎯 目标:帮助不同层级的前端工程师系统化准备面试,涵盖一线互联网公司真实面试题

📊 适用范围:阿里巴巴、腾讯、字节跳动、美团、京东、百度等一线互联网公司

🔄 更新频率:持续更新最新技术趋势和面试题目

📚 目录索引

🎯 按工作经验分层

📋 按题型分类

🔧 按技术栈分类


初级工程师(1-2年经验)

基础概念题

1. JavaScript数据类型和类型检测

问题描述
请详细说明JavaScript的数据类型,并解释如何准确检测各种数据类型?

核心考点

  • 基本数据类型和引用数据类型的理解
  • 类型检测方法的掌握程度
  • 对JavaScript类型系统的认知

标准答案

JavaScript数据类型分为两大类:

基本数据类型(7种)

  1. undefined - 未定义
  2. null - 空值
  3. boolean - 布尔值
  4. number - 数字
  5. string - 字符串
  6. symbol - 符号(ES6新增)
  7. bigint - 大整数(ES2020新增)

引用数据类型(1种)

  • object - 对象(包括普通对象、数组、函数、日期等)

类型检测方法

  1. typeof操作符
typeof undefined    // "undefined"
typeof null        // "object" (历史遗留问题)
typeof true        // "boolean"
typeof 42          // "number"
typeof "hello"     // "string"
typeof Symbol()    // "symbol"
typeof 123n        // "bigint"
typeof {
   
   }          // "object"
typeof []          // "object"
typeof function(){
   
   } // "function"
  1. Object.prototype.toString.call()
Object.prototype.toString.call(null)        // "[object Null]"
Object.prototype.toString.call([])          // "[object Array]"
Object.prototype.toString.call(new Date())  // "[object Date]"
Object.prototype.toString.call(/regex/)     // "[object RegExp]"
  1. instanceof操作符
[] instanceof Array        // true
new Date() instanceof Date // true
  1. Array.isArray()
Array.isArray([])    // true
Array.isArray({
   
   })    // false

代码示例

// 通用类型检测函数
function getType(value) {
   
   
  if (value === null) return 'null';
  if (typeof value !== 'object') return typeof value;
  
  const objectType = Object.prototype.toString.call(value);
  return objectType.slice(8, -1).toLowerCase();
}

// 测试
console.log(getType(null));        // "null"
console.log(getType([]));          // "array"
console.log(getType(new Date()));  // "date"
console.log(getType(/regex/));     // "regexp"

扩展知识点

  • typeof null 返回 “object” 的历史原因
  • Symbol类型的使用场景和特性
  • BigInt类型解决的精度问题
  • 类型转换的隐式规则

难度标记:⭐
频率标记:🔥🔥🔥

2. 闭包的概念和应用

问题描述
什么是闭包?请举例说明闭包的实际应用场景。

核心考点

  • 闭包的定义和形成条件
  • 作用域链的理解
  • 闭包的实际应用能力

标准答案

闭包定义
闭包是指有权访问另一个函数作用域中变量的函数。简单说,闭包就是函数内部的函数可以访问外部函数的变量。

形成条件

  1. 函数嵌套
  2. 内部函数引用外部函数的变量
  3. 内部函数被外部调用或返回

代码示例

// 基础闭包示例
function outerFunction(x) {
   
   
  // 外部函数的变量
  let outerVariable = x;
  
  // 内部函数(闭包)
  function innerFunction(y) {
   
   
    console.log(outerVariable + y); // 访问外部变量
  }
  
  return innerFunction;
}

const closure = outerFunction(10);
closure(5); // 输出: 15

实际应用场景

  1. 模块化封装
const Calculator = (function() {
   
   
  let result = 0; // 私有变量
  
  return {
   
   
    add: function(num) {
   
   
      result += num;
      return this;
    },
    subtract: function(num) {
   
   
      result -= num;
      return this;
    },
    getResult: function() {
   
   
      return result;
    }
  };
})();

Calculator.add(10).subtract(3).getResult(); // 7
  1. 函数柯里化
function curry(fn) {
   
   
  return function curried(...args) {
   
   
    if (args.length >= fn.length) {
   
   
      return fn.apply(this, args);
    } else {
   
   
      return function(...nextArgs) {
   
   
        return curried.apply(this, args.concat(nextArgs));
      };
    }
  };
}

const add = (a, b, c) => a + b + c;
const curriedAdd = curry(add);
console.log(curriedAdd(1)(2)(3)); // 6
  1. 防抖和节流
function debounce(func, delay) {
   
   
  let timeoutId;
  return function(...args) {
   
   
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func.apply(this, args), delay);
  };
}

const debouncedSearch = debounce(function(query) {
   
   
  console.log('搜索:', query);
}, 300);

扩展知识点

  • 闭包的内存泄漏问题
  • 垃圾回收机制对闭包的影响
  • 箭头函数中的闭包特性
  • 闭包在异步编程中的应用

难度标记:⭐⭐
频率标记:🔥🔥🔥

3. 原型和原型链

问题描述
请解释JavaScript中的原型和原型链机制,以及它们在继承中的作用。

核心考点

  • 原型对象的概念
  • 原型链的查找机制
  • 继承的实现原理

标准答案

原型(Prototype)
每个JavaScript对象都有一个原型对象,原型对象也是一个普通对象。对象可以从原型对象继承属性和方法。

原型链(Prototype Chain)
当访问对象的属性时,如果对象本身没有该属性,JavaScript会沿着原型链向上查找,直到找到该属性或到达原型链的顶端(null)。

关键概念

  • __proto__:对象的原型引用(非标准,但广泛支持)
  • prototype:函数的原型属性
  • constructor:指向构造函数的引用

代码示例

// 构造函数
function Person(name) {
   
   
  this.name = name;
}

// 在原型上添加方法
Person.prototype.sayHello = function() {
   
   
  console.log(`Hello, I'm ${
     
     this.name}`);
};

// 创建实例
const person1 = new Person('Alice');
const person2 = new Person('Bob');

// 原型链查找
person1.sayHello(); // "Hello, I'm Alice"

// 验证原型关系
console.log(person1.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true

继承实现

// 父类
function Animal(name) {
   
   
  this.name = name;
}

Animal.prototype.speak = function() {
   
   
  console.log(`${
     
     this.name} makes a sound`);
};

// 子类
function Dog(name, breed) {
   
   
  Animal.call(this, name); // 调用父类构造函数
  this.breed = breed;
}

// 设置原型链继承
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

// 子类特有方法
Dog.prototype.bark = function() {
   
   
  console.log(`${
     
     this.name} barks`);
};

const dog = new Dog('Buddy', 'Golden Retriever');
dog.speak(); // "Buddy makes a sound"
dog.bark();  // "Buddy barks"

ES6 Class语法

class Animal {
   
   
  constructor(name) {
   
   
    this.name = name;
  }
  
  speak() {
   
   
    console.log(`${
     
     this.name} makes a sound`);
  }
}

class Dog extends Animal {
   
   
  constructor(name, breed) {
   
   
    super(name);
    this.breed = breed;
  }
  
  bark() {
   
   
    console.log(`${
     
     this.name} barks`);
  }
}

扩展知识点

  • Object.create() 的使用和原理
  • instanceof 操作符的工作机制
  • 原型污染的安全问题
  • Mixin模式的实现

难度标记:⭐⭐
频率标记:🔥🔥🔥

原理深入题

4. 事件循环机制

问题描述
请详细解释JavaScript的事件循环机制,包括宏任务和微任务的执行顺序。

核心考点

  • 单线程执行模型的理解
  • 宏任务和微任务的区别
  • 异步编程的底层机制

标准答案

事件循环(Event Loop)
JavaScript是单线程语言,事件循环是JavaScript处理异步操作的机制,它决定了代码的执行顺序。

执行栈(Call Stack)
同步代码按顺序执行,形成执行栈。

任务队列(Task Queue)

  • 宏任务(Macro Task):setTimeout、setInterval、I/O操作、UI渲染
  • 微任务(Micro Task):Promise.then、queueMicrotask、MutationObserver

执行顺序

  1. 执行同步代码
  2. 执行所有微任务
  3. 执行一个宏任务
  4. 重复步骤2-3

代码示例

console.log('1'); // 同步任务

setTimeout(() => {
   
   
  console.log('2'); // 宏任务
}, 0);

Promise.resolve().then(() => {
   
   
  console.log('3'); // 微任务
});

console.log('4'); // 同步任务

// 输出顺序: 1, 4, 3, 2

复杂示例

console.log('start');

setTimeout(() => {
   
   
  console.log('timeout1');
  Promise.resolve().then(() => {
   
   
    console.log('promise1');
  });
}, 0);

Promise.resolve().then(() => {
   
   
  console.log('promise2');
  setTimeout(() => {
   
   
    console.log('timeout2');
  }, 0);
});

console.log('end');

// 输出顺序: start, end, promise2, timeout1, promise1, timeout2

扩展知识点

  • Node.js中的事件循环差异
  • async/await的执行机制
  • requestAnimationFrame的执行时机
  • 浏览器渲染与事件循环的关系

难度标记:⭐⭐⭐
频率标记:🔥🔥🔥


中级工程师(3-5年经验)

实战场景题

5. 性能优化实战

问题描述
在一个大型单页应用中,你发现首屏加载时间过长,请描述你的性能优化思路和具体实施方案。

核心考点

  • 性能分析能力
  • 优化方案的系统性思考
  • 实际项目经验

标准答案

性能分析步骤

  1. 性能指标测量
// 使用Performance API测量关键指标
const observer = new PerformanceObserver((list) => {
   
   
  for (const entry of list.getEntries()) {
   
   
    if (entry.entryType === 'navigation') {
   
   
      console.log('DNS查询时间:', entry.domainLookupEnd - entry.domainLookupStart);
      console.log('TCP连接时间:', entry.connectEnd - entry.connectStart);
      console.log('首字节时间:', entry.responseStart - entry.requestStart);
      console.log('DOM解析时间:', entry.domContentLoadedEventEnd - entry.responseEnd);
    }
  }
});

observer.observe({
   
    entryTypes: ['navigation'] });
  1. 资源加载分析
// 分析资源加载性能
const resources = performance.getEntriesByType('resource');
const largeResources = resources.filter(resource => 
  resource.transferSize > 100 * 1024 // 大于100KB的资源
);

console.log('大文件资源:', largeResources);

优化方案

  1. 代码分割和懒加载
// 路由级别的代码分割
const routes = [
  {
   
   
    path: '/home',
    component: () => import(/* webpackChunkName: "home" */ '@/views/Home.vue')
  },
  {
   
   
    path: '/dashboard',
    component: () => import(/* webpackChunkName: "dashboard" */ '@/views/Dashboard.vue')
  }
];

// 组件级别的懒加载
const LazyComponent = defineAsyncComponent({
   
   
  loader: () => import('./HeavyComponent.vue'),
  loadingComponent: LoadingSpinner,
  errorComponent: ErrorComponent,
  delay: 200,
  timeout: 3000
});
  1. 资源优化
// 图片懒加载
const useImageLazyLoad = () => {
   
   
  const imageObserver = new IntersectionObserver((entries) => {
   
   
    entries.forEach(entry => {
   
   
      if (entry.isIntersecting) {
   
   
        const img = entry.target;
        img.src = img.dataset.src;
        img.classList.remove('lazy');
        imageObserver.unobserve(img);
      }
    });
  });

  const observeImages = () => {
   
   
    const lazyImages = document.querySelectorAll('img[data-src]');
    lazyImages.forEach(img => imageObserver.observe(img));
  };

  return {
   
    observeImages };
};
  1. 缓存策略
// Service Worker缓存
self.addEventListener('fetch', event => {
   
   
  if (event.request.destination === 'image') {
   
   
    event.respondWith(
      caches.open('images-cache').then(cache => {
   
   
        return cache.match(event.request).then(response => {
   
   
          if (response) {
   
   
            return response;
          }
          return fetch(event.request).then(fetchResponse => {
   
   
            cache.put(event.request, fetchResponse.clone());
            return fetchResponse;
          });
        });
      })
    );
  }
});
  1. 预加载策略
// 关键资源预加载
const preloadCriticalResources = () => {
   
   
  const criticalResources = [
    '/api/user/profile',
    '/api/dashboard/summary'
  ];

  criticalResources.forEach(url => {
   
   
    fetch(url, {
   
    
      method: 'GET',
      priority: 'high' 
    }).then(response => {
   
   
      // 缓存响应数据
      caches.open('api-cache').then(cache => {
   
   
        cache.put(url, response.clone());
      });
    });
  });
};

量化结果

  • 首屏加载时间从3.2s优化到1.8s(减少44%)
  • 资源体积从2.1MB减少到1.3MB(减少38%)
  • Lighthouse性能评分从65分提升到92分

扩展知识点

  • Core Web Vitals指标优化
  • HTTP/2和HTTP/3的性能优势
  • CDN配置和边缘计算
  • 构建工具的优化配置

难度标记:⭐⭐⭐
频率标记:🔥🔥🔥


高级工程师(5年以上经验)

架构设计题

6. 微前端架构设计

问题描述
设计一个支持多团队协作的微前端架构,需要考虑技术选型、通信机制、部署策略等方面。

核心考点

  • 大型系统架构设计能力
  • 技术选型的权衡考虑
  • 团队协作的技术方案

标准答案

架构设计思路

  1. 技术选型对比
方案 优势 劣势 适用场景
Single-SPA 成熟稳定、生态丰富 学习成本高 大型企业应用
qiankun 开箱即用、阿里维护 定制化程度低 中大型项目
Module Federation Webpack原生支持 版本依赖复杂 现代化项目
iframe 隔离性好、简单 性能差、体验差 遗留系统集成
  1. 架构设计方案
// 主应用架构
interface MicroFrontendConfig {
   
   
  name: string;
  entry: string;
  container: string;
  activeRule: string;
  props?: Record<string, any>;
}

class MicroFrontendManager {
   
   
  private apps: Map<string, MicroFrontendConfig> = new Map();
  private globalState: GlobalStateManager;
  private eventBus: EventBus;

  constructor() {
   
   
    this.globalState = new GlobalStateManager();
    this.eventBus = new EventBus();
    this.setupGlobalErrorHandler();
  }

  // 注册微应用
  registerApp(config: MicroFrontendConfig) {
   
   
    this.apps.set(config.name, config);
    
    // 配置应用间通信
    this.setupAppCommunication(config.name);
  }

  // 应用间通信机制
  private setupAppCommunication(appName: string) {
   
   
    // 1. 全局状态共享
    this.globalState.subscribe(appName, (state) => {
   
   
      this.eventBus.emit(`${
     
     appName}:state-change`, state);
    });

    // 2. 事件总线
    this.eventBus.on(`${
     
     appName}:action`, (payload) => {
   
   
      this.handleAppAction(appName, payload);
    });
  }

  // 全局错误处理
  private setupGlobalErrorHandler() {
   
   
    window.addEventListener('error', (event) => {
   
   
      this.reportError({
   
   
        type: 'javascript-error',
        message: event.message,
        filename: event.filename,
        lineno: event.lineno,
        colno: event.colno,
        stack: event.error?.stack
      });
    });

    window.addEventListener('unhandledrejection', (event) => {
   
   
      this.reportError({
   
   
        type: 'promise-rejection',
        reason: event.reason
      });
    });
  }
}
  1. 通信机制设计
// 全局状态管理
class GlobalStateManager {
   
   
  private state: Map<string, any> = new Map();
  private subscribers: Map<string, Set<Function>> = new Map();

  setState(key: string, value: any) {
   
   
    const oldValue = this.state.get(key);
    this.state.set(key, value);
    
    // 通知订阅者
    this.notifySubscribers(key, value, oldValue);
  }

  getState(key: string) {
   
   
    return this.state.get(key);
  }

  subscribe(key: string, callback: Function) {
   
   
    if (!this.subscribers.has(key)) {
   
   
      this.subscribers.set(key, new Set());
    }
    this.subscribers.get(key)!.add(callback);

    // 返回取消订阅函数
    return () => {
   
   
      this.subscribers.get(key)?.delete(callback);
    };
  }

  private notifySubscribers(key: string, newValue: any, oldValue: any) {
   
   
    const callbacks = this.subscribers.get(key);
    if (callbacks) {
   
   
      callbacks.forEach(callback => {
   
   
        try {
   
   
          callback(newValue, oldValue);
        } catch (error) {
   
   
          console.error('State subscriber error:', error);
        }
      });
    }
  }
}

// 事件总线
class EventBus {
   
   
  private events: Map<string, Set<Function>> = new Map();

  on(event: string, callback: Function) {
   
   
    if (!this.events.has(event)) {
   
   
      this.events.set(event, new Set());
    }
    this.events.get(event)!.add(callback);
  }

  emit(event: string, ...args: any[]) {
   
   
    const callbacks = this.events.get(event);
    if (callbacks) {
   
   
      callbacks.forEach(callback => {
   
   
        try {
   
   
          callback(...args);
        } catch (error) {
   
   
          console.error('Event callback error:', error);
        }
      });
    }
  }

  off(event: string, callback: Function) {
   
   
    this.events.get(event)?.delete(callback);
  }
}
  1. 部署策略
# Docker部署配置
version: '3.8'
services:
  # 主应用
  shell-app:
    build: ./apps/shell
    ports:
      - "3000:80"
    environment:
      - NODE_ENV=production
    depends_on:
      - user-app
      - order-app
      - product-app

  # 用户中心微应用
  user-app:
    build: ./apps/user
    ports:
      - "3001:80"
    environment:
      - NODE_ENV=production

  # 订单系统微应用
  order-app:
    build: ./apps/order
    ports:
      - "3002:80"
    environment:
      - NODE_ENV=production

  # 商品管理微应用
  product-app:
    build: ./apps/product
    ports:
      - "3003:80"
    environment:
      - NODE_ENV=production

  # Nginx网关
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - shell-app
  1. 监控和治理
// 微前端监控系统
class MicroFrontendMonitor {
   
   
  private performanceMetrics: Map<string, any> = new Map();
  private errorReports: Array<any> = [];

  // 性能监控
  trackPerformance(appName: string) {
   
   
    const observer = new PerformanceObserver((list) => {
   
   
      const entries = list.getEntries();
      entries.forEach(entry => {
   
   
        if (entry.entryType === 'navigation') {
   
   
          this.performanceMetrics.set(appName, {
   
   
            loadTime: entry.loadEventEnd - entry.loadEventStart,
            domContentLoaded: entry.domContentLoadedEventEnd - entry.domContentLoadedEventStart,
            firstPaint: performance.getEntriesByName('first-paint')[0]?.startTime,
            firstContentfulPaint: performance.getEntriesByName('first-contentful-paint')[0]?.startTime
          });
        }
      });
    });

    observer.observe({
   
    entryTypes: ['navigation'] });
  }

  // 错误监控
  trackErrors(appName: string) {
   
   
    window.addEventListener('error', (event) => {
   
   
      this.errorReports.push({
   
   
        app: appName,
        type: 'javascript-error',
        message: event.message,
        filename: event.filename,
        timestamp: Date.now()
      });
    });
  }

  // 生成监控报告
  generateReport() {
   
   
    return {
   
   
      performance: Object.fromEntries(this.performanceMetrics),
      errors: this.errorReports,
      timestamp: Date.now()
    };
  }
}

扩展知识点

  • 微前端的样式隔离方案
  • 共享依赖的版本管理
  • 渐进式迁移策略
  • 性能优化和监控体系

难度标记:⭐⭐⭐
频率标记:🔥🔥


📊 面试准备策略

🎯 不同层级的重点准备方向

初级工程师

  • 重点掌握JavaScript基础概念
  • 熟练使用Vue/React基本API
  • 了解基础的工程化工具
  • 能够解决常见的开发问题

中级工程师

  • 深入理解框架原理和设计思想
  • 具备性能优化的实战经验
  • 掌握复杂业务场景的解决方案
  • 能够进行技术选型和架构设计

高级工程师

  • 具备大型系统的架构设计能力
  • 拥有团队技术管理经验
  • 能够解决复杂的技术难题
  • 具备前瞻性的技术视野

📚 推荐学习资源

官方文档

进阶学习

  • 《JavaScript高级程序设计》
  • 《你不知道的JavaScript》
  • 《深入理解ES6》
  • 《前端架构:从入门到微前端》

实战项目

  • 参与开源项目贡献
  • 搭建个人技术博客
  • 实现经典算法和数据结构
  • 构建完整的全栈项目


JavaScript核心

7. 深拷贝和浅拷贝的实现

问题描述
请实现一个深拷贝函数,并说明与浅拷贝的区别。需要考虑各种数据类型和边界情况。

核心考点

  • 对象引用和值传递的理解
  • 递归算法的应用
  • 边界情况的处理能力

标准答案

浅拷贝 vs 深拷贝

  • 浅拷贝:只复制对象的第一层属性,嵌套对象仍然是引用
  • 深拷贝:递归复制对象的所有层级,创建完全独立的副本

浅拷贝实现

// 方法1:Object.assign
const shallowCopy1 = Object.assign({
   
   }, originalObj);

// 方法2:扩展运算符
const shallowCopy2 = {
   
   

网站公告

今日签到

点亮在社区的每一天
去签到