面试篇:(四)JavaScript 深入理解 - 2024 年前端面试技巧与面试题汇总

JavaScript 深入理解 - 2024 年前端面试技巧与面试题汇总

JavaScript 是前端开发的核心,无论你使用哪种框架或库,面试中都离不开对 JavaScript 的考察。本篇将深入讲解 JavaScript 常见的面试题目及其背后的原理,帮助你在面试中从容应对复杂问题,展现扎实的基础功底。


1. 闭包(Closure)

(1) 什么是闭包?

:闭包的定义是什么?它的常见应用场景有哪些?

:闭包是指函数能够“记住”并访问它的词法作用域(lexical scope)中的变量,即使函数在它的定义作用域之外执行。换句话说,闭包是在一个函数内部定义的另一个函数,内部函数可以访问外部函数的变量和参数,甚至在外部函数执行完毕后依然可以访问。

常见应用场景

  • 数据封装:通过闭包实现私有变量,外部无法直接访问或修改这些变量。
  • 回调函数:如事件处理函数、定时器函数中的闭包。
  • 柯里化:函数接收部分参数后返回一个新函数,后续传入更多参数继续执行。

示例

function createCounter() {
   
  let count = 0;  // 外部函数作用域中的变量
  return function() {
     // 内部函数形成闭包
    count++;
    return count;
  };
}

const counter = createCounter();
console.log(counter());  // 输出: 1
console.log(counter());  // 输出: 2

2. 原型链与继承

(2) 什么是原型链?

:JavaScript 中的原型链如何工作?如何实现继承?

:原型链是 JavaScript 实现继承的一种方式。在 JavaScript 中,每个对象都有一个 __proto__ 属性,指向它的原型对象,而原型对象又有自己的 __proto__,依此类推,形成一个原型链。当访问对象的某个属性时,如果对象本身没有这个属性,JavaScript 会沿着原型链向上查找,直到找到该属性或到达原型链的尽头。

继承的实现

  • 构造函数继承:通过将子类构造函数中的 this 绑定到父类构造函数来继承属性。
  • 原型继承:通过设置子类的原型对象为父类的实例对象来继承方法。

示例

function Animal(name) {
   
  this.name = name;
}

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

function Dog(name) {
   
  Animal.call(this, name);  // 调用父类构造函数继承属性
}

Dog.prototype = Object.create(Animal.prototype);  // 继承父类方法
Dog.prototype.constructor = Dog;

const dog = new Dog('Rex');
dog.speak();  // 输出: Rex makes a sound.

3. 作用域与作用域链

(3) 什么是作用域链?

:JavaScript 中如何工作作用域链?为什么它很重要?

:作用域链是在 JavaScript 中查找变量的一种机制。当在一个函数中访问一个变量时,JavaScript 会首先在当前函数的作用域中查找,如果未找到则沿着作用域链依次向上查找,直到全局作用域。

作用域链的主要功能是保证变量的可见性和隔离性,防止不同作用域中的变量发生冲突。

示例

let globalVar = 'global';

function outerFunction() {
   
  let outerVar = 'outer';
  
  function innerFunction() {
   
    let innerVar = 'inner';
    console.log(globalVar);  // 输出: global
    console.log(outerVar);   // 输出: outer
    console.log(innerVar);   // 输出: inner
  }
  
  innerFunction();
}

outerFunction();

4. 事件循环(Event Loop)

(4) 什么是事件循环?

:JavaScript 的事件循环是如何工作的?它与异步操作有何关系?

:JavaScript 是单线程语言,它通过事件循环来管理异步操作。事件循环的主要作用是监控任务队列(task queue)中的任务,并将任务推入执行栈中运行。

  • 同步任务:直接在调用栈中按顺序执行。
  • 异步任务:如 setTimeoutPromise 等,会先被推入任务队列中,当调用栈为空时,事件循环会检查任务队列,将任务推入调用栈执行。

事件循环执行顺序

  1. 执行所有同步代码。
  2. 遇到异步任务,将其放入任务队列。
  3. 执行微任务队列中的任务(如 Promise)。
  4. 执行宏任务队列中的任务(如 setTimeout)。

示例

console.log('Start')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全栈探索者chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值