闭包、原型链与继承、手写Promise

Tips:为了拿掘金的矿石写的文章,水一下;可以随便看看。

闭包与变量保存

闭包在 JavaScript 中是一个十分常见但容易被滥用的概念。一个典型的面试问题是:如何利用闭包实现私有变量?

以下代码展示了一个简单的闭包实现私有变量的例子:

javascript 复制代码
function createCounter() {
  let count = 0;  // 私有变量,外部无法直接访问
  return {
    increment: function() {
      count += 1;
      return count;
    },
    decrement: function() {
      count -= 1;
      return count;
    }
  };
}

const counter = createCounter();
console.log(counter.increment()); // 输出: 1
console.log(counter.decrement()); // 输出: 0

这个例子中,createCounter 返回一个对象,该对象的方法内部能访问到 createCounter 作用域内的 count 变量。面试官可能会追问闭包的内存泄漏风险以及如何正确管理作用域问题,这要求候选人不仅理解语法,还需要关注代码在大规模项目下的性能和可维护性。

原型链与继承

面试中往往会要求手写实现一个继承机制或者解释原型链的工作原理。理解原型链对于深入掌握 JavaScript 对象模型至关重要。以下代码示例展示了构造函数、原型对象及其相互关联的基本模型:

javascript 复制代码
function Person(name) {
  this.name = name;
}
Person.prototype.sayHi = function() {
  console.log(`Hi, I'm ${this.name}`);
};

function Student(name, school) {
  Person.call(this, name); // 继承属性
  this.school = school;
}

// 继承方法
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

Student.prototype.study = function() {
  console.log(`${this.name} is studying at ${this.school}`);
};

const student = new Student('Alice', 'MIT');
student.sayHi();    // 输出: Hi, I'm Alice
student.study();    // 输出: Alice is studying at MIT

这里展示了如何用 Object.create 实现对父类 Person 原型的继承,同时正确设置构造函数属性。面试中可能还会问及 ES6 中 class 语法的实现原理,候选人需要对语法糖和底层原型链机制之间的关系有清晰认识。

异步编程与 Promise 实现

异步编程是前端工程中的难点之一,面试官常常会询问如何手写一个简单的 Promise。下面提供一个 Promise 简易实现的片段:

ini 复制代码
class MyPromise {
  constructor(executor) {
    this.status = 'pending';
    this.value = null;
    this.reason = null;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

    const resolve = (value) => {
      if (this.status === 'pending') {
        this.status = 'fulfilled';
        this.value = value;
        this.onFulfilledCallbacks.forEach(fn => fn());
      }
    };

    const reject = (reason) => {
      if (this.status === 'pending') {
        this.status = 'rejected';
        this.reason = reason;
        this.onRejectedCallbacks.forEach(fn => fn());
      }
    };

    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }

  then(onFulfilled, onRejected) {
    if (this.status === 'fulfilled') {
      onFulfilled(this.value);
    } else if (this.status === 'rejected') {
      onRejected(this.reason);
    } else {
      this.onFulfilledCallbacks.push(() => onFulfilled(this.value));
      this.onRejectedCallbacks.push(() => onRejected(this.reason));
    }
    // 简化未返回新的 Promise 的实现
  }
}

// 测试 MyPromise 实现
new MyPromise((resolve, reject) => {
  setTimeout(() => resolve('Success!'), 1000);
}).then(
  value => console.log(value),    // 一秒后输出: Success!
  error => console.error(error)
);

通过这个简单的 Promise 实现,面试官旨在验证候选人对异步处理流程、错误捕获以及状态管理的理解。候选人可以进一步讨论如链式调用、异常冒泡等更深入的实现问题。

相关推荐
FungLeo8 小时前
成为全栈·React 管理后台篇·总复盘:从“接口能调通”到“后台值得使用”
前端·react.js·前端框架·项目复盘·成为全栈
Csvn9 小时前
并发模式:让渲染学会排队、插队和让路
前端
可乐鸡翅yeah_10 小时前
新手梳理:M3U8 线上问题,哪些是前端锅,哪些是后端锅
前端·ios·音视频·实时音视频·m3u8·音视频在线播放
Flynt10 小时前
Linear 用 1000 个 PR 换掉 styled-components,我写了 200 个按钮,把这笔账复现了一遍
前端·css·preact
JavaGuide11 小时前
NVIDIA 又开源了!这次给 AI Agent 加上权限管控
前端·后端
excel11 小时前
prisma 如何处理数据库竞态
前端·数据库·后端
莪_幻尘12 小时前
Skill 体检:30 个 Skill 全凭感觉?体检器先自曝了 8 个“假 0 分
前端·人工智能·llm
风骏时光牛马12 小时前
AI模型综合能力评测:性能、指令遵循与多场景实测对比
前端
Frag0ut12 小时前
Chrome与Chromium内核浏览器在Windows 11上的新特性全景解析
前端·chrome·windows·web安全·chromium·gemini ai·playready drm
hiahiahia12313 小时前
实现完整 Tool Dispatcher
开发语言·前端