参透 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 博客 | 掘金专栏

交流讨论

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

相关推荐
FelixBitSoul9 小时前
彻底吃透 React Hook:它背后的执行模型到底是什么? 🚀
前端
Huanzhi_Lin9 小时前
Nginx本地资源服务器-常用脚本
服务器·前端·nginx·batch·静态资源服务器
weixin199701080169 小时前
《好看视频商品详情页前端性能优化实战》
前端·性能优化·音视频
有意义9 小时前
深入理解浏览器存储方案:从Cookie到JWT登录认证
前端·面试·浏览器
jiayong239 小时前
第 6 课:第二轮真实重构,拆出任务表格组件
前端·重构
jiayong239 小时前
第 4 课:怎么把一个大页面拆成多个组件
运维·服务器·前端
skywalk816310 小时前
使用DuMate帮助创建 Python 3.9 环境并部署 Kotti CMS
前端·chrome
英俊潇洒美少年10 小时前
Vue Hook 与 React Hook 全面解析:区别、用法、实战及避坑指南
前端·vue.js·react.js
吴声子夜歌10 小时前
ES6——Symbol详解
开发语言·javascript·es6