深入理解New操作符

简介: 深入理解New操作符

前言


当我们对函数进行实例化时,需要用new操作符来实现。那么,对于它的底层实现原理你是否清楚呢?本文就跟大家分享下它的原理并用一个函数来模拟实现它,欢迎各位感兴趣的开发者阅读本文。


原理分析


我们通过一个具体的例子来看下一个函数在new之后都能做些什么,如下所示:


function Person(name, age) {
  this.name = name;
  this.age = age;
  this.height = "175cm";
  this.bodyWeight = "65kg";
  return "some anything";
}
// 每日运动量
Person.prototype.dailyExercise = "300 kcal";
Person.prototype.printBodyWeight = function() {
  console.log(this.name + "体重为: " + this.bodyWeight);
};

接下来,我们用new关键字将Person函数进行实例化,我们发现实例化后,可以访问到:


  • 函数内部的属性
  • 函数原型上的属性


const person = new Person("神奇的程序员", "22");
console.log(person.age);
console.log(person.bodyWeight);
console.log(person.dailyExercise);
person.printBodyWeight();


640.png

                              image-20221005120945478


眼尖的开发者可能已经发现我们的构造函数中返回了一个字符串,它是属于基本类型,如果我们返回一个对象会发生什么?


function Person(name, age) {
  //... 其他代码省略 ...//
  return {
    bodyWeight: this.bodyWeight
  };
}


再次运行代码后,我们发现:


  • 只能访问我们在构造函数中所返回的属性
  • 构造函数中声明的其它属性以及挂载在原型上的属性均无法访问


640.png

                             image-20221005160504245


实现思路


经过前面的分析,我们知道了函数在new完之后会返回一个新的对象,这个对象上挂载了构造函数内的所有属性以及函数原型上的所有属性。


我们在实现的时候,也需要建立一个新的对象,这个对象上需要包含构造函数里的属性,因此我们可以使用apply方法来给此对象添加新属性。


在深入理解原型链与继承文章中,我们知道实例的 __proto__属性会指向构造函数的prototype,建立起这样的关系后,实例才可以访问原型上的属性。


有了这些知识点作为铺垫后,我们就可以写出这个模拟函数了,如下所示:


  • 创建一个对象用来存储构造函数的属性
  • 从arguments中取出第一个参数,这个参数便是调用时的构造函数
  • 将新对象的原型通过__proto__指向构造函数的prototype
  • 通过apply方法改变构造函数的this指向,从而实现将构造函数内部的属性添加进新创建的对象中
  • 判断构造函数是否有返回值
  • 有返回值且其类型为一个对象或者一个函数,则返回构造函数的返回值
  • 否则就返回我们新创建的对象


function instantiateFactory() {
  const obj = {};
  // 取出第一个参数: 函数的构造函数
  const Constructor = [].shift.call(arguments);
  // 将新对象的原型指向构造函数
  obj.__proto__ = Constructor.prototype;
  // 改变构造函数的this指向至新创建的对象
  const result = Constructor.apply(obj, arguments);
  // 如果构造函数有返回值且它的值为对象或者函数则将其返回
  if (result && (typeof result == "object" || typeof result == "function")) {
    return result;
  }
  // 否则返回此对象
  return obj;
}


测试用例


我们用原理分析中的例子来验证下我们实现的这个工厂函数能否正确执行。


const factory = instantiateFactory(Person, "神奇的程序员", "22");
console.log(factory.age);
console.log(factory.bodyWeight);
console.log(factory.dailyExercise);
factory.printBodyWeight();


假设函数没有返回值或者返回值是一个字符串类型时,执行结果如下所示:


640.png

                                 image-20221005222833333


当函数的返回值是一个对象时,执行结果如下所示:


640.png

                               image-20221005222930129


代码地址


本文为《JS原理学习》系列的第7篇文章,本系列的完整路线请移步:《JS原理学习 (1) 》学习路线规划


本系列文章的所有示例代码,请移步:js-learning


写在最后


至此,文章就分享完毕了。


我是神奇的程序员,一位前端开发工程师。


如果你对我感兴趣,请移步我的个人网站,进一步了解。

  • 公众号无法外链,如果文中有链接,可点击下方阅读原文查看😊
相关文章
|
10天前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
全网爆火的 Jev 模型是什么?有什么用?怎么使用?怎么接入 AI 编程工具?效果真的好么?傻子可懂的 Jev 保姆级实战教程 + 项目实战测评来啦
7759 13
|
8天前
|
人工智能 测试技术 API
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
Jev是TypeSafe AI推出的“系统一模型”,不生成文本,专做毫秒级结构化决策:Choice(多选)、Score(打分)、Noul(是非概率)。响应快193倍、成本低444倍,适合工单路由、内容审核、测试定级等高频判断场景。
1676 4
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
|
5天前
|
人工智能 JavaScript 芯片
DeepSeek 官方偷偷上传 Harness 桌面端安装包,我已经用上了。。附最新下载地址
DeepSeek Harness 官方的桌面端安装包被网友扒出来了,2 分钟讲明白如何使用,体验如何,适合作为 AI 编程工具么?附最新 Windows 和 Mac 双端的下载地址
1454 1
|
9天前
|
人工智能 并行计算 PyTorch
秋叶 ComfyUI 2026 整合包 v3.2 完整部署教程:Python 3.13 + Torch 2.13 全栈升级
秋叶aaaki ComfyUI 2026年8月整合包v3.2正式发布!全面升级Python 3.13.11、PyTorch 2.13.0+cu130及ComfyUI v0.30.2,原生支持MiniMax H3、Wan 2.2、Qwen-Image-2.1等2026主流音视频/图像模型,解压即用,无需环境配置。
1359 11
|
22天前
|
人工智能 自然语言处理 安全
阿里云千问办公 QwenWork详细介绍:产品核心能力、典型场景、价格及常见问题解答
千问办公是阿里云推出的一站式AI办公平台,主打"不止于对话,更注重交付",依托通义千问旗舰大模型,用户一句话即可完成数据分析、PPT生成、视频剪辑等复杂任务,直接输出可用成果。产品深度打通钉钉生态与企业OA,覆盖桌面端、网页端,提供企业标准版198元/人/月等多档订阅方案,新用户注册即赠2000积分,适配工程师、HR、财务等多职业办公场景,成为能动手干活的"全能AI同事"。
3710 10
|
7天前
|
人工智能 编解码 并行计算
MiniMax-H3 一键整合包技术文档:8G 显存运行 AI 漫剧制作 —— 角色替换 / 动作迁移 / 文图生视频部署与调参指南
MiniMax H3 是 MiniMax 开源的全模态视频生成模型,支持文/图/音/视多条件输入,输出最高2K、15秒带双声道音频视频。本文档详述其Int8量化版在8GB显存下的本地一键部署、三段式工作流(EDIT/REPLACE/CONTINUE)、参数调优及常见问题排查。(239字)
|
17天前
|
缓存 IDE Java
【保姆级】Android Studio下载、安装和汉化教程(2026最新)
Android Studio 是 Google 官方推出的免费 Android 应用开发集成环境,基于 IntelliJ IDEA,内置模拟器、调试器、性能分析及 Compose 界面工具,功能全面,文档丰富,是安卓开发首选工具。(239字)
1815 1

热门文章

最新文章