闭包、原型链与继承、手写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 实现,面试官旨在验证候选人对异步处理流程、错误捕获以及状态管理的理解。候选人可以进一步讨论如链式调用、异常冒泡等更深入的实现问题。

相关推荐
极小狐9 分钟前
极狐GitLab 容器镜像仓库功能介绍
java·前端·数据库·npm·gitlab
程序猿阿伟21 分钟前
《Flutter社交应用暗黑奥秘:模式适配与色彩的艺术》
前端·flutter
rafael(一只小鱼)25 分钟前
黑马点评实战笔记
前端·firefox
weifont25 分钟前
React中的useSyncExternalStore使用
前端·javascript·react.js
初遇你时动了情30 分钟前
js fetch流式请求 AI动态生成文本,实现逐字生成渲染效果
前端·javascript·react.js
影子信息44 分钟前
css 点击后改变样式
前端·css
几何心凉1 小时前
如何使用 React Hooks 替代类组件的生命周期方法?
前端·javascript·react.js
小堃学编程1 小时前
前端学习(1)—— 使用HTML编写一个简单的个人简历展示页面
前端·javascript·html
hnlucky2 小时前
通俗易懂版知识点:Keepalived + LVS + Web + NFS 高可用集群到底是干什么的?
linux·前端·学习·github·web·可用性测试·lvs
懒羊羊我小弟2 小时前
使用 ECharts GL 实现交互式 3D 饼图:技术解析与实践
前端·vue.js·3d·前端框架·echarts