参透 JavaScript —— 彻底理解 new 操作符及手写实现

前言

本篇文章主要理解 new 操作符的原理,并手写实现一个自己的 "new"

new 操作符在背后做了什么?

在上篇文章中讲解了原型与原型链,讲到了使用 new 操作符创建实例对象

  1. 为什么 new 操作符创建的对象会拥有构造函数上的全部属性和方法?
  2. 为什么实例对象上的原型指针会指向构造函数的原型?

要明白这些问题,就要知道 new 操作符在实例化时做了什么

翻开《JavaScript 高级程序设计》第四版中关于原型的篇章,当以 new 关键字调用函数时,会执行以下操作:

  1. 在内存中创建一个新对象
  2. 这个新对象内部的 [[Prototype]] 特性被赋值为构造函数的 prototyoe 属性
  3. 构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)
  4. 执行构造函数内部的代码(给新对象添加属性)
  5. 如果构造函数返回非空对象,返回这个对象;否则,返回新创建的对象

手写自己的 new 操作符

按照上面流程,我们可以模拟写一个自己的 new

比如,我们拥有一个 myNew 函数

js 复制代码
function myNew(constructor, ...args) {
  // 1.在内存中创建一个新对象
  // 2.这个新对象内部的 `[[Prototype]]` 特性被赋值为构造函数的 prototyoe 属性
  const obj = Object.create(constructor.prototype);

  // 3. 构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)
  // 4. 执行构造函数内部的代码(给新对象添加属性)
  const result = constructor.apply(obj, args);

  // 5. 如果构造函数返回非空对象,返回这个对象;否则,返回新创建的对象
  return (result !== null && typeof result === 'object') ? result : obj;
}

解析:

使用 Object.create 来实现第一步、第二步,这个方法会创建一个新对象,并且将新对象的原型指针指向传入的对象的原型

在第三步和第四步,使用了函数上的实例方法 Function.protytype.apply

这个方法会改变函数内部的 this 指向,并且将剩余的参数(arguments)作为数组传入,然后调用该函数

手写的效果

在谷歌浏览器 - F12 开发者工具上测试效果

总结

实例对象拥有构造函数的全部属性和方法,并且原型指针指向构造函数的原型,都是 new 操作符在背后做的工作:

  1. 在内存中创建一个新对象
  2. 这个新对象内部的 [[Prototype]] 特性被赋值为构造函数的 prototyoe 属性
  3. 构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)
  4. 执行构造函数内部的代码(给新对象添加属性)
  5. 如果构造函数返回非空对象,返回这个对象;否则,返回新创建的对象

记住,手写实现 new 操作符,本质是为了实践理解 new 操作符的背后原理

参考资料

参透JavaScript系列

本文已收录至《参透 JavaScript 系列》,全文地址:我的 GitHub 博客 | 掘金专栏

交流讨论

对文章内容有任何疑问、建议,或发现有错误,欢迎交流和指正

相关推荐
Csvn6 小时前
OpenSpec 详细使用教程
前端
之歆7 小时前
Day19_LESS 完全指南——从入门到工程实践
前端·css·less
云水一下8 小时前
HTML5 从入门到精通:实战收官——从零搭建完整静态网站,综合运用所有知识
前端·html5
不总是8 小时前
Windows 系统 Node.js 免安装版(zip)安装与配置教程(2026 最新)
前端·windows·node.js
冬奇Lab8 小时前
每日一个开源项目(第105篇):Twenty - 跳出 Salesforce 的圈套,定义现代开源 CRM
前端·后端·开源
zhangyao9403309 小时前
开发pc端时,表格的高度怎么设置才能铺满页面
前端·javascript·elementui
XinZong9 小时前
实测OpenClaw虾淘:全民工具AI时代,冷门非工具类的Skill还能出圈吗?
javascript
kjs--9 小时前
浏览器书签执行脚本
前端
烛衔溟9 小时前
TypeScript 类的类型 —— 作为类型使用
javascript·ubuntu·typescript
之歆10 小时前
Day16_JavaScript 轮播图与事件工程实战(下篇)
服务器·开发语言·前端·javascript·网络·性能优化