深入浅出:从JS的new运算符到手写ES5/ES6版实现

深入浅出:从JS的new运算符到手写ES5/ES6版实现

一、JS中的new运算符本质

当我们使用new Person('awei',20)时,JS引擎会默默完成以下关键步骤:

javascript 复制代码
function Person(name, age) {
  this.name = name
  this.age = age
}
Person.prototype.sayName = function() {
  console.log(this.name)
}

const awei = new Person('awei', 20)

执行流程解析

  1. 创建纯净对象 :在堆内存中开辟新空间,生成空对象{}

  2. 建立原型链 :将空对象的__proto__指向构造函数的prototype

  3. 绑定执行上下文 :将构造函数内部的this指向这个新对象

  4. 执行构造函数 :相当于执行Person.call(obj, 'awei', 20)

  5. 返回结果处理

    • 构造函数无返回值时自动返回新对象
    • 若返回非对象类型则仍返回新对象
    • 若返回对象则直接使用该返回值

二、ES5环境手写new实现

ini 复制代码
function objectFactory() {
  const obj = new Object();
  const Constructor = [].shift.call(arguments);
  
  obj.__proto__ = Constructor.prototype;
  const ret = Constructor.apply(obj, arguments);
  
  return typeof ret === 'object' ? ret : obj;
}

// 测试用例
let awei = objectFactory(Person, 'awei', 20)

实现要点

  1. 通过arguments处理参数(类数组转数组)

  2. 使用shift方法分离构造函数

  3. 显式设置原型链(比JSON创建对象更灵活)

  4. 处理构造函数返回值:

    • 返回对象时优先采用
    • 非对象类型返回新实例

三、ES6环境优化版实现

javascript 复制代码
function objectFactory(fn, ...args) {
  const obj = {};
  obj.__proto__ = fn.prototype;
  
  const ret = fn.apply(obj, args);
  return ret instanceof Object ? ret : obj;
}

// 支持特殊返回值
function Person() {
  return { tag: 'custom object' }
}

const instance = objectFactory(Person)

升级优化点

  1. 参数处理:使用剩余参数...args替代arguments
  2. 空对象创建:对象字面量{}更高效
  3. 返回值判断:instanceof检测更严谨
  4. 支持箭头函数:通过原型链动态绑定

四、核心差异对比

特性 ES5实现 ES6实现
参数处理 arguments+shift 剩余参数...args
空对象创建 new Object() 对象字面量{}
原型设置 显式__proto__赋值 同左
返回值判断 typeof检测 instanceof检测
构造函数类型支持 仅标准函数 支持箭头函数(需特殊处理)

特殊场景处理

  • 当构造函数返回null时,typeof null === 'object'null instanceof Object === false
  • 箭头函数作为构造函数时需配合Object.setPrototypeOf处理
  • 需要兼容SymbolBigInt等基本类型返回值时需扩展类型判断

理解new运算符的底层实现,不仅能帮助开发者应对面试考点,更能深入理解原型链工作机制。当我们需要创建具有特殊初始化逻辑的对象,或需要自定义对象创建过程时,手写new的实现方式将展现出强大的灵活性。

相关推荐
华玥作者10 小时前
[特殊字符] VitePress 对接 Algolia AI 问答(DocSearch + AI Search)完整实战(下)
前端·人工智能·ai
Mr Xu_10 小时前
告别冗长 switch-case:Vue 项目中基于映射表的优雅路由数据匹配方案
前端·javascript·vue.js
前端摸鱼匠10 小时前
Vue 3 的toRefs保持响应性:讲解toRefs在解构响应式对象时的作用
前端·javascript·vue.js·前端框架·ecmascript
sleeppingfrog11 小时前
zebra通过zpl语言实现中文打印(二)
javascript
lang2015092811 小时前
JSR-340 :高性能Web开发新标准
java·前端·servlet
好家伙VCC12 小时前
### WebRTC技术:实时通信的革新与实现####webRTC(Web Real-TimeComm
java·前端·python·webrtc
未来之窗软件服务12 小时前
未来之窗昭和仙君(六十五)Vue与跨地区多部门开发—东方仙盟练气
前端·javascript·vue.js·仙盟创梦ide·东方仙盟·昭和仙君
baidu_2474386112 小时前
Android ViewModel定时任务
android·开发语言·javascript
嘿起屁儿整12 小时前
面试点(网络层面)
前端·网络
VT.馒头12 小时前
【力扣】2721. 并行执行异步函数
前端·javascript·算法·leetcode·typescript