前端手写: new操作符

手写 new 操作符

1. new 操作符的工作原理

javascript 复制代码
// new 操作符做了以下4件事:
// 1. 创建一个空对象
// 2. 将这个空对象的原型指向构造函数的 prototype
// 3. 将构造函数的 this 绑定到这个新对象
// 4. 执行构造函数
// 5. 返回这个新对象(如果构造函数没有返回对象,则返回 this)

function Person(name, age) {
  this.name = name;
  this.age = age;
}

// 使用 new
const p1 = new Person('张三', 25);

2. 手写 myNew 函数

2.1 基础版本

javascript 复制代码
function myNew(constructor, ...args) {
  // 1. 创建一个新对象
  const obj = {};
  
  // 2. 将对象的原型指向构造函数的 prototype
  obj.__proto__ = constructor.prototype;
  // 或者使用:Object.setPrototypeOf(obj, constructor.prototype);
  
  // 3. 将构造函数的 this 绑定到新对象,并执行构造函数
  const result = constructor.apply(obj, args);
  
  // 4. 判断构造函数返回值类型
  // 如果构造函数返回一个对象,则返回这个对象
  // 否则返回新创建的对象
  return result instanceof Object ? result : obj;
}

3. 面试常考版本(精简)

javascript 复制代码
// 面试时能写出的最简版本
function myNew(Con, ...args) {
  const obj = Object.create(Con.prototype);
  const result = Con.apply(obj, args);
  return result instanceof Object ? result : obj;
}

4. 实现原理详解

javascript 复制代码
// 详细解释每一步
function explainNew(constructor, ...args) {
  console.log('1. 获取构造函数:', constructor);
  
  // 步骤1:创建空对象
  console.log('2. 创建一个空对象');
  const obj = {};
  
  // 步骤2:设置原型链
  console.log('3. 设置对象的原型为构造函数的 prototype');
  console.log('   构造函数 prototype:', constructor.prototype);
  obj.__proto__ = constructor.prototype;
  console.log('   新对象的 __proto__:', obj.__proto__);
  
  // 步骤3:执行构造函数
  console.log('4. 执行构造函数,绑定 this 到新对象');
  console.log('   构造函数参数:', args);
  const result = constructor.apply(obj, args);
  console.log('   构造函数返回值:', result);
  console.log('   新对象当前状态:', obj);
  
  // 步骤4:判断返回值
  console.log('5. 判断构造函数返回值类型');
  const shouldReturnResult = result && (typeof result === 'object' || typeof result === 'function');
  console.log('   应该返回构造函数返回值吗?', shouldReturnResult);
  
  return shouldReturnResult ? result : obj;
}

// 测试
function Demo(name) {
  this.name = name;
  this.createdAt = new Date();
}
const demo = explainNew(Demo, '测试');

5. 常见面试问题

Q1: new 操作符做了什么?

A:

  1. 创建一个新对象
  2. 将这个对象的原型指向构造函数的 prototype
  3. 将构造函数的 this 绑定到这个新对象,并执行构造函数
  4. 如果构造函数返回一个对象,则返回这个对象;否则返回新创建的对象

Q2: 手写 new 操作符的思路?

A:

javascript 复制代码
function myNew(Con, ...args) {
  // 1. 创建对象,设置原型
  const obj = Object.create(Con.prototype);
  // 2. 执行构造函数
  const result = Con.apply(obj, args);
  // 3. 判断返回值
  return result instanceof Object ? result : obj;
}

Q3: 构造函数返回基本类型会怎样?

A: 如果构造函数返回基本类型(string, number, boolean, null, undefined),这个返回值会被忽略,new 操作符会返回新创建的对象。

Q4: 构造函数返回对象会怎样?

A: 如果构造函数返回一个对象(包括数组、函数),那么这个对象会作为 new 表达式的结果,而不是新创建的对象。

Q5: 箭头函数能用 new 调用吗?

A: 不能。箭头函数没有自己的 this,也没有 prototype 属性,所以不能作为构造函数使用。

6. 总结

手写 new 的核心步骤

  1. 创建对象:创建一个新对象
  2. 设置原型 :将对象的 __proto__指向构造函数的 prototype
  3. 绑定 this :使用 applycall将构造函数的 this 绑定到新对象
  4. 执行构造函数:传入参数执行
  5. 返回结果:判断构造函数返回值,如果是对象则返回,否则返回新对象

一句话总结:new 操作符就是创建一个新对象,将其原型指向构造函数的 prototype,然后以这个对象为 this 执行构造函数,最后根据构造函数返回值决定返回什么。

相关推荐
猫3282 分钟前
echarts 日常问题解决
前端·javascript·echarts
新中地GIS开发老师6 分钟前
地信职业百科④:GIS开发工程师
前端·数据库·gis·webgis·三维gis开发
我是大卫14 分钟前
【图】React源码解析-从数据结构、调度器、源码设计模式到状态计算引擎,深挖useReducer原理
前端·react.js·源码
willes21 分钟前
列表中的倒计时组件
前端
LVZ23 分钟前
用了半年 AI 写代码,最烦的不是代码,是环境
前端·后端·开源
polaris_tl24 分钟前
一行 `compress: false`,为什么让 SSE 首包恢复实时返回
前端
海边的云25 分钟前
别再让 AI 瞎改代码:一套让大模型「收敛」的前端专家 Skill》
前端
kisshyshy26 分钟前
给端侧大模型装上“发动机”:React 合成事件 + 进度条组件全解
前端·react.js·node.js
hunterandroid37 分钟前
DataStore 工程化实践:迁移、并发更新与异常恢复
android·前端
晓说前端37 分钟前
TypeScript 核心语法进阶 —— 字面量类型与类型推论
前端·typescript