前端JS面试6大核心考点详解

这是前端JS核心面试必考6大知识点代码分析题+进阶题 全集,严格遵循JS执行逻辑,覆盖基础必考题+进阶拔高题,每题附代码、输出结果、逐行详解,完全适配中大厂前端面试要求。

前端JS核心面试题详解(作用域/this/对象/闭包/原型/异步)

核心考点优先级

  1. this指向、异步(事件循环/Promise)⭐⭐⭐⭐⭐
  2. 闭包、原型链 ⭐⭐⭐⭐
  3. 作用域、对象 ⭐⭐⭐

一、作用域 & 作用域链 & 变量提升

核心原理

  1. 三种作用域:全局作用域、函数作用域、块级作用域(let/const
  2. 变量提升:var 声明提升、let/const 存在暂时性死区
  3. 作用域链:内层函数访问变量时,逐级向上查找外层作用域

基础题1:var 变量提升

js 复制代码
console.log(a);
var a = 10;
console.log(a);

输出undefined10
详解

  1. JS预编译:var a 声明提升到顶部,赋值保留原地 → 代码等价于:

    js 复制代码
    var a;
    console.log(a); // 仅声明未赋值 → undefined
    a = 10;
    console.log(a); // 赋值完成 → 10

基础题2:let 暂时性死区

js 复制代码
console.log(b);
let b = 20;

输出Uncaught ReferenceError: Cannot access 'b' before initialization
详解let/const 存在块级作用域和暂时性死区,声明前无法访问,无变量提升。

进阶题1:嵌套作用域 + 作用域链

js 复制代码
var num = 1;
function fn1() {
  var num = 2;
  function fn2() {
    num = 3; 
    function fn3() {
      console.log(num);
    }
    fn3();
  }
  fn2();
}
fn1();
console.log(num);

输出31
详解

  1. fn3 无自身num,沿作用域链找到fn2修改的num=3,打印3
  2. 所有修改都在函数作用域 内,全局num不受影响,最终打印1

二、this指向(面试第一考点)

核心绑定规则(优先级从高到低)

  1. new 绑定 → 2. 显式绑定 (call/apply/bind)→ 3. 隐式绑定 → 4. 默认绑定
  2. 箭头函数:无自己的this,继承外层作用域的this

基础题1:默认绑定(独立函数调用)

js 复制代码
var name = "全局";
function fn() {
  console.log(this.name);
}
fn();

输出全局
详解 :全局独立调用函数,this默认指向全局对象(浏览器=window)。

基础题2:隐式绑定(对象方法调用)

js 复制代码
const obj = {
  name: "对象",
  fn: function() {
    console.log(this.name);
  }
}
obj.fn();

输出对象
详解 :谁调用方法,this就指向谁 → obj调用,this=obj

基础题3:箭头函数this

js 复制代码
const obj = {
  name: "箭头",
  fn: () => {
    console.log(this.name);
  }
}
obj.fn();

输出undefined(浏览器严格模式)/ 全局
详解 :箭头函数无this,继承外层全局作用域的this,而非obj。

进阶题1:混合绑定优先级(必考)

js 复制代码
function Person(name) {
  this.name = name;
}
const obj = {};
const fn = Person.bind(obj); 
fn("张三"); 
console.log(obj.name); 

const p = new fn("李四"); 
console.log(p.name); 

输出张三李四
详解

  1. bind显式绑定objfn("张三")this=objobj.name=张三
  2. new绑定优先级高于bindnew fnthis指向新实例,覆盖bind绑定。

进阶题2:定时器 + this + 箭头函数

js 复制代码
const obj = {
  name: "定时器",
  fn1: function() {
    setTimeout(function() {
      console.log(this.name); 
    }, 0);
  },
  fn2: function() {
    setTimeout(() => {
      console.log(this.name);
    }, 0);
  }
}
obj.fn1();
obj.fn2();

输出undefined定时器
详解

  1. 普通函数定时器:回调是独立调用 → 默认绑定window,无name
  2. 箭头函数定时器:继承fn2this(指向obj),正常打印。

三、对象 & 属性 & 深浅拷贝

核心原理

  1. 对象属性:自有属性/原型属性,hasOwnProperty判断自有属性
  2. 浅拷贝:只拷贝一层,引用类型共享内存
  3. 深拷贝:递归拷贝所有层级,完全独立

基础题1:in / hasOwnProperty

js 复制代码
const obj = { a: 1 };
console.log('a' in obj); 
console.log('toString' in obj); 
console.log(obj.hasOwnProperty('toString')); 

输出truetruefalse
详解

  1. in:检查自有+原型属性;
  2. hasOwnProperty:仅检查自有属性toString是Object原型属性。

进阶题1:浅拷贝的坑(高频)

js 复制代码
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { ...obj1 }; 
obj2.a = 10;
obj2.b.c = 20;
console.log(obj1.a, obj1.b.c);

输出120
详解

  1. 扩展运算符是浅拷贝 ,基础类型a独立,引用类型b共享内存;
  2. 修改obj2.b.c会同步修改原对象。

四、闭包(高频必考)

核心定义

函数能够访问并保留其词法作用域,即使在词法作用域外执行,就形成闭包。

作用:私有化变量、模块化、保存数据

基础题1:闭包基础

js 复制代码
function outer() {
  let num = 10;
  function inner() {
    console.log(num);
  }
  return inner;
}
const fn = outer();
fn(); 

输出10
详解innerouter外部执行,仍能访问outernum → 闭包。

基础题2:经典循环闭包BUG(var)

js 复制代码
for (var i = 0; i < 3; i++) {
  setTimeout(() => {
    console.log(i);
  }, 0);
}

输出333
详解

  1. var是函数作用域,循环共用一个i
  2. 定时器是异步,执行时循环已结束,i=3

进阶题1:闭包修复循环(两种方案)

js 复制代码
// 方案1:let 块级作用域
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 0);
}
// 方案2:闭包包裹
for (var i = 0; i < 3; i++) {
  (function(j){
    setTimeout(() => console.log(j), 0);
  })(i)
}

输出012
详解

  1. let每次循环生成独立块级作用域;
  2. 立即执行函数创建独立作用域,保存每次的i值。

五、原型 & 原型链 & 继承

核心原理

  1. 实例.proto = 构造函数.prototype
  2. 原型链终点:Object.prototype.__proto__ = null
  3. instanceof:判断构造函数的prototype是否在实例的原型链上

基础题1:原型链属性查找

js 复制代码
function Person() {}
Person.prototype.name = "原型";
const p = new Person();
p.name = "实例";
console.log(p.name); 
delete p.name;
console.log(p.name); 

输出实例原型
详解

  1. 先找实例自有属性,有则直接用;
  2. 删除实例属性后,沿原型链找到Person.prototypename

进阶题1:组合继承(面试必考)

js 复制代码
function Parent(name) {
  this.name = name;
}
Parent.prototype.say = function() {
  console.log(this.name);
}
function Child(name, age) {
  Parent.call(this, name); 
  this.age = age;
}
Child.prototype = Object.create(Parent.prototype); 
Child.prototype.constructor = Child; 

const c = new Child("小明", 18);
c.say();
console.log(c.age);

输出小明18
详解

  1. Parent.call:继承实例属性;
  2. Object.create:继承原型方法,完美实现JS组合继承。

六、异步编程(Promise/async/await/事件循环)

核心原理(浏览器)

  1. 执行顺序:同步代码 → 微任务 → 宏任务
  2. 微任务:Promise.then/catch/finallyprocess.nextTick
  3. 宏任务:setTimeoutsetInterval、AJAX、DOM事件

基础题1:Promise链式调用

js 复制代码
Promise.resolve()
  .then(() => console.log(1))
  .then(() => console.log(2));
Promise.resolve()
  .then(() => console.log(3));

输出132
详解 :微任务队列按顺序执行,第一个链的then1执行完,执行第二个then3,最后执行第一个then2

进阶题1:async/await 执行顺序(终极面试题)

js 复制代码
async function async1() {
  console.log('async1 start');
  await async2();
  console.log('async1 end');
}
async function async2() {
  console.log('async2');
}
console.log('script start');
setTimeout(() => console.log('setTimeout'), 0);
async1();
new Promise(resolve => {
  console.log('Promise');
  resolve();
}).then(() => console.log('Promise then'));
console.log('script end');

输出
script startasync1 startasync2Promisescript endasync1 endPromise thensetTimeout
详解

  1. 同步代码优先执行:script startasync1 startasync2Promisescript end
  2. await 后面的代码 = 微任务,Promise.then 也是微任务,按顺序执行;
  3. 最后执行宏任务setTimeout

进阶题2:Promise.all 异常处理

js 复制代码
const p1 = Promise.resolve(1);
const p2 = Promise.reject("错误");
const p3 = Promise.resolve(3);
Promise.all([p1, p2, p3])
  .then(res => console.log(res))
  .catch(err => console.log(err));

输出错误
详解Promise.all 只要有一个失败,整体直接失败,返回第一个错误。


总结(面试必背核心结论)

  1. this:new > 显式 > 隐式 > 默认,箭头函数继承外层this;
  2. 闭包 :函数访问外层作用域变量,解决循环问题用let/立即执行函数;
  3. 原型链 :实例通过__proto__找原型,自有属性优先级高于原型;
  4. 异步:同步 → 微任务(Promise)→ 宏任务(定时器);
  5. 作用域var函数作用域+提升,let块级作用域+暂时性死区。
相关推荐
ai大模型中转api测评2 小时前
2026年前端新工具:Gemini 3.1 SVG工作流从Prompt到部署
前端·人工智能·prompt·api
yyuuuzz2 小时前
独立站搭建:从基础到避坑的实战分享
前端·javascript·github
Trouvaille ~2 小时前
【MySQL篇】内外连接:多表关联的完整指南
android·数据库·mysql·面试·后端开发·dql·内外连接
星空椰2 小时前
JavaScript 基础入门:从零开始掌握变量与数据类型
开发语言·前端·javascript·ecmascript
千寻简2 小时前
一个让 Claude Code 顺手很多的状态栏插件:claude-hud
前端·后端
掘金者阿豪2 小时前
数据库安全第一关:用户密码存储与认证机制的深度拆解
java·前端·后端
MgArcher2 小时前
Python高级特性:sorted() 排序完全指南
前端·后端
Ruihong2 小时前
你的 Vue 3 生命周期,VuReact 会编译成什么样的 React?
vue.js·react.js·面试
MgArcher2 小时前
Python高级特性:返回函数与闭包完全指南
前端·后端