深入理解 JavaScript:从手写 new 到类数组 arguments,大厂面试高频考点全解析

47 阅读3分钟

在前端工程师的面试中,尤其是面向一线大厂(如阿里、腾讯、字节、美团等)时,JavaScript 的底层原理与运行机制往往是考察的重点。本文将围绕两个经典而高频的面试题展开:

  • 如何手写实现 new 操作符?
  • 函数中的 arguments 是什么?它真的是数组吗?

通过这两个问题,我们将深入探讨 JavaScript 中的原型链、构造函数、this 绑定、类数组对象等核心概念,并辅以代码实践与思考延伸,助你真正掌握这些知识点背后的逻辑。


一、手写 new:理解对象实例化的全过程

1.1 new 做了什么?

当你写下:

function Person(name) {
  this.name = name;
}
const p = new Person('Alice');

JavaScript 引擎实际上完成了以下四件事:

  1. 创建一个全新的空对象
  2. 将这个新对象的 [[Prototype]](即 __proto__)指向构造函数的 prototype
  3. 将构造函数内部的 this 绑定到这个新对象,并执行构造函数;
  4. 如果构造函数没有显式返回一个引用类型(对象/数组/函数等),则自动返回新创建的对象。

1.2 手写实现 myNew

基于上述逻辑,我们可以轻松实现自己的 new

function myNew(constructor, ...args) {
  // 1. 创建空对象,继承构造函数的原型
  const obj = Object.create(constructor.prototype);
  
  // 2. 执行构造函数,绑定 this
  const result = constructor.apply(obj, args);
  
  // 3. 判断是否返回了对象,若是则返回该对象,否则返回新对象
  return (typeof result === 'object' && result !== null) ? result : obj;
}

1.3 验证效果

function Car(brand) {
  this.brand = brand;
}

const car1 = myNew(Car, 'Tesla');
console.log(car1.brand); // Tesla
console.log(car1 instanceof Car); // true

✅ 完美复刻原生 new 行为!

💡 思考延伸:如果构造函数返回一个基本类型(如 return 42),会发生什么?答案是:依然返回新对象。只有返回非 null 的对象才会覆盖默认行为。


二、arguments:被误解的“类数组”

2.1 什么是 arguments

在非箭头函数中,arguments 是一个自动可用的局部变量,它包含了调用时传入的所有参数。

function add() {
  console.log(arguments); // [1, 2, 3](看起来像数组)
}
add(1, 2, 3);

但它不是真正的数组!它是一个类数组对象(Array-like Object)

2.2 类数组 vs 真数组

特性arguments真数组
length 属性
可通过索引访问元素
继承自 Array.prototype
能用 map / reduce / join 等方法?

验证一下:

function test() {
  console.log(arguments instanceof Array); // false
  console.log(Array.isArray(arguments));    // false
  console.log(Object.prototype.toString.call(arguments)); // "[object Arguments]"
}

2.3 如何将 arguments 转为真数组?

有多种方式:

// ES6+ 推荐
const args = [...arguments];

// 或使用 Array.from
const args = Array.from(arguments);

// 传统方式(兼容性好)
const args = [].slice.call(arguments);

转换后即可使用所有数组方法:

function sum() {
  const nums = [...arguments];
  return nums.reduce((a, b) => a + b, 0);
}
console.log(sum(1, 2, 3, 4)); // 10

⚠️ 注意:箭头函数中没有 arguments!需使用剩余参数(...args)替代。


三、面试官想考察什么?

这两个问题看似简单,实则暗藏玄机:

  • new 的实现 → 考察你对原型链、this 绑定、对象创建机制的理解;
  • arguments 的本质 → 考察你对数据类型、内置对象、ES 规范细节的掌握。

能清晰解释并手写代码,说明你不仅会用 API,更理解 JavaScript 的运行时模型。


四、总结与建议

知识点关键理解
new 操作符对象创建四步曲,原型链连接,this 绑定
arguments类数组 ≠ 数组,无数组方法,需转换
类数组对象length + 索引属性,但不继承 Array.prototype
实践建议多手写核心机制(如 call/apply/bind/new),加深理解

🌟 结语

前端面试早已不是“会用框架”就能过关的时代。大厂更看重你对语言本质的理解。知其然,更要知其所以然

下次当面试官问:“你能手写 new 吗?”——你可以自信地写出代码,并娓娓道来背后的原理。

真正的高手,不是记住答案的人,而是理解问题本质的人。