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

相关推荐
yong99905 分钟前
MATLAB倍频转换效率分析与最佳匹配角模拟
开发语言·前端·matlab
面向星辰10 分钟前
扣子开始节点和结束节点
java·服务器·前端
执携23 分钟前
Vue Router (命名视图)
前端·javascript·vue.js
John_Rey27 分钟前
Rust类型系统奇技淫巧:幽灵类型(PhantomData)——理解编译器与类型安全
前端·安全·rust
含若飞1 小时前
Vue 中 `watch` 与 `this.$watch` 使用指南
前端·javascript·vue.js
无名小兵2 小时前
前端渲染大体积 多页面pdf
前端
c0detrend2 小时前
读诗的时候我却使用了自己研发的Chrome元素截图插件
前端·chrome
希冀1232 小时前
【Vue】第五篇
前端·javascript·vue.js
Moonbit2 小时前
你行你上!MoonBit LOGO 重构有奖征集令
前端·后端·设计
littleplayer3 小时前
Root-> A ->B -> C page, 当前C page, 如何返回B,又如何直接返回A page呢
前端