返回

赋值面试题巧解,揭秘 JS 引擎执行机制

前端

手写 JS 引擎来解释一道赋值面试题?这道题的答案看似简单,但背后却隐藏着 JS 引擎执行机制的奥秘。本文将以实战演练的方式,带你手把手构建一个 JS 引擎,深入理解赋值操作的执行过程。

赋值面试题剖析

面试题:

const a = {};
a.x = {n: 2};
const preA = a;
a = null;
console.log(preA.x.n); // 输出什么?

答案: undefined

解释:

JS 引擎在执行赋值操作时,是从左往右进行的。因此,首先将 {n: 2} 赋值给 a.x,然后再将 {n: 2} 赋值给 a。当我们将 a 赋值为 null 时,实际上只是改变了 a 的引用,而不会影响 preA 所引用的对象。因此,preA.x.n 的值为 2,即输出 undefined

手写 JS 引擎

为了深入理解赋值操作的执行过程,我们来手写一个简单的 JS 引擎。该引擎将仅支持基本的对象和赋值操作。

// 模拟 JS 引擎
const engine = {
  // 对象存储
  objects: {},

  // 获取对象引用
  getObject(objRef) {
    return this.objects[objRef];
  },

  // 设置对象属性
  setProperty(objRef, prop, value) {
    const obj = this.getObject(objRef);
    obj[prop] = value;
  },

  // 赋值操作
  assign(leftRef, rightRef) {
    const left = this.getObject(leftRef);
    const right = this.getObject(rightRef);

    if (typeof left === "object") {
      this.setProperty(leftRef, "value", right);
    } else {
      this.objects[leftRef] = right;
    }
  },
};

实战演练

使用我们手写的 JS 引擎,来一步步执行面试题中的赋值操作:

  1. 创建一个空对象,并获取其引用
const aObjRef = engine.objects.length;
  1. 为对象设置 x 属性,并赋值 {n: 2}
engine.setProperty(aObjRef, "x", {n: 2});
  1. 创建 preA,并指向 a 对象
const preAObjRef = aObjRef;
  1. a 对象赋值为 null
engine.objects[aObjRef] = null;
  1. 获取 preA.x.n 的值
const preAXn = engine.getObject(preAObjRef).x.n;

通过以上步骤,我们可以验证面试题的输出结果为 undefined

总结

通过手写 JS 引擎并实战演练,我们深入理解了赋值操作的执行过程,揭秘了 JS 引擎的执行机制。这种实践性的学习方法,可以有效提升我们的编程思维和技术能力。