new原理解析

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 本文深入解析了JavaScript中的new关键字,介绍了其作用、原理,并提供了一些代码示例来帮助读者更好地理解。通过对new关键字的详细解析,我们可以更好地理解JavaScript中对象实例的创建过程,从而更加灵活地运用new关键字来构建复杂的应用程序。

new关键字的介绍

在JavaScript中,new是一个用于创建对象实例的关键字。当使用new关键字调用一个函数时,它会执行以下操作:

  1. 创建一个空的简单 JavaScript 对象(即 {} );
  2. 为步骤 1 新创建的对象添加属性 __proto__ ,将该属性链接至构造函数的原型对象;
  3. 将步骤 1 新创建的对象作为 this 的上下文;
  4. 如果该函数没有返回对象,则返回 this

语法

newconstructor[([arguments])]

参数

  • constructor
    一个指定对象实例的类型的类或函数。
  • arguments
    一个用于被 constructor 调用的参数列表。

创建一个用户自定义的对象需要两步:

  1. 通过编写函数来定义对象类型。
  2. 通过 new 来创建对象实例。

new关键字的原理

为了更好地理解new关键字背后的原理,我们可以手动实现一个简化版的new操作符。下面是一个示例代码:

functionmyNew(constructor, ...args) {
// 创建一个空对象constobj= {};
// 将空对象的原型指向构造函数的prototype属性Object.setPrototypeOf(obj, constructor.prototype);
// 将构造函数内部的this指向这个空对象constresult=constructor.apply(obj, args);
// 如果构造函数返回了一个对象,则返回该对象;否则返回新创建的对象returntypeofresult==='object'&&result!==null?result : obj;
}

通过上述代码,我们可以手动实现一个类似于new关键字的操作。

首先,我们创建一个空对象obj,并将其原型指向构造函数的prototype属性。

然后,我们将构造函数内部的this指向这个空对象,并执行构造函数内部的代码。最后,根据构造函数的返回值决定返回新创建的对象还是该返回值。

new关键字的代码示例

下面是一个使用new关键字创建对象实例的示例代码:

functionPerson(name, age) {
this.name=name;
this.age=age;
}
Person.prototype.sayHello=function() {
console.log(`Hello, my name is ${this.name}and I'm ${this.age}years old.`);
}
constjohn=newPerson('John', 25);
john.sayHello(); // 输出:Hello, my name is John and I'm 25 years old.

在上述示例中,我们定义了一个Person构造函数,并在其原型上添加了一个sayHello方法。

然后,通过使用new关键字调用Person构造函数来创建一个名为johnPerson实例。最后,我们调用john实例上的sayHello方法来输出一段问候语。

new个对象呗

functionBoyfriend(name, age) {
this.name=name;
this.age=age;
this.gender="male";
this.isCool=true;
}
functionGirlfriend(name, age) {
this.name=name;
this.age=age;
this.gender="female";
this.isBeautiful=true;
}
constjohn=newBoyfriend("John", 25);
constlisa=newGirlfriend("Lisa", 23);
console.log(john); // 输出:Boyfriend { name: 'John', age: 25, gender: 'male', isCool: true }console.log(lisa); // 输出:Girlfriend { name: 'Lisa', age: 23, gender: 'female', isBeautiful: true }

在上述示例中,我们定义了两个构造函数:Boyfriend和Girlfriend。

这两个构造函数分别用于创建男朋友和女朋友的对象实例。

每个构造函数都接受名字和年龄作为参数,并在对象实例中设置相应的属性(如姓名、年龄、性别和是否正帅气或者漂亮)。通过使用new关键字调用这两个构造函数,我们可以分别创建一个名为john的男朋友对象和一个名为lisa的女朋友对象。最后,我们打印出这两个对象实例,可以看到它们分别具有相应的属性值。

new.target

new.target是一个在构造函数内部可用的元属性(meta property),它提供了一个指向正在被构造的实例的构造函数的引用。它可以用来确定构造函数是通过new关键字被调用还是直接调用。

下面是一些关于new.target的详细介绍:

  1. 使用方式:
  • 在构造函数内部,可以通过访问new.target来获取正在被构造的实例的构造函数。
  • 如果构造函数是通过new关键字被调用,那么new.target将指向该构造函数本身。
  • 如果构造函数是直接调用(而不是通过new关键字),那么new.target将为undefined。
  1. 功能:
  • 可以使用new.target来执行一些特定于构造函数调用的逻辑。例如,可以根据是否使用了new关键字来决定是否执行某些初始化操作。
  • 可以使用new.target来实现基于类的继承。在派生类中,可以通过super关键字和new.target来访问父类的构造函数。

下面是一个示例代码,演示了如何使用new.target:

functionPerson(name) {
if (typeofnew.target==="undefined") {
thrownewError("Person must be instantiated using new");
  }
this.name=name;
}
functionStudent(name, grade) {
Person.call(this, name);
this.grade=grade;
}
Student.prototype=Object.create(Person.prototype);
Student.prototype.constructor=Student;
constjohn=newPerson("John"); // 正常调用,创建一个Person实例console.log(john.name); // 输出:Johnconstlisa=newStudent("Lisa", 10); // 正常调用,创建一个Student实例console.log(lisa.name); // 输出:Lisaconsole.log(lisa.grade); // 输出:10constmark=Person.call({}, "Mark"); // 错误调用,没有使用new关键字

在上述示例中,我们定义了一个Person构造函数和一个Student构造函数。

在Person构造函数内部,我们使用new.target来检查是否使用了new关键字。如果没有使用new关键字,则抛出一个错误。

在Student构造函数中,我们通过调用Person.call(this, name)来调用父类的构造函数,并传递相应的参数。然后,我们通过Object.create和prototype链来实现基于类的继承。

结论

本文深入解析了JavaScript中的new关键字,介绍了其作用、原理,并提供了一些代码示例来帮助读者更好地理解。通过对new关键字的详细解析,我们可以更好地理解JavaScript中对象实例的创建过程,从而更加灵活地运用new关键字来构建复杂的应用程序。

new.target是一个在构造函数内部可用的元属性,它提供了一个指向正在被构造的实例的构造函数的引用。它可以用来确定构造函数是通过new关键字被调用还是直接调用,并且可以执行特定于构造函数调用的逻辑或实现基于类的继承。

目录
相关文章
|
20天前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
38 3
|
1月前
|
C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(二)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
1月前
|
编译器 C++ 开发者
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
1月前
|
存储 C语言 C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(一)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
7天前
|
算法 Java 数据库连接
Java连接池技术,从基础概念出发,解析了连接池的工作原理及其重要性
本文详细介绍了Java连接池技术,从基础概念出发,解析了连接池的工作原理及其重要性。连接池通过复用数据库连接,显著提升了应用的性能和稳定性。文章还展示了使用HikariCP连接池的示例代码,帮助读者更好地理解和应用这一技术。
22 1
|
13天前
|
数据采集 存储 编解码
一份简明的 Base64 原理解析
Base64 编码器的原理,其实很简单,花一点点时间学会它,你就又消除了一个知识盲点。
42 3
|
1月前
|
前端开发 Java 应用服务中间件
21张图解析Tomcat运行原理与架构全貌
【10月更文挑战第2天】本文通过21张图详细解析了Tomcat的运行原理与架构。Tomcat作为Java Web开发中最流行的Web服务器之一,其架构设计精妙。文章首先介绍了Tomcat的基本组件:Connector(连接器)负责网络通信,Container(容器)处理业务逻辑。连接器内部包括EndPoint、Processor和Adapter等组件,分别处理通信、协议解析和请求封装。容器采用多级结构(Engine、Host、Context、Wrapper),并通过Mapper组件进行请求路由。文章还探讨了Tomcat的生命周期管理、启动与停止机制,并通过源码分析展示了请求处理流程。
|
28天前
|
开发框架 缓存 前端开发
electron-builder 解析:你了解其背后的构建原理吗?
本文首发于微信公众号“前端徐徐”,详细解析了 electron-builder 的工作原理。electron-builder 是一个专为整合前端项目与 Electron 应用的打包工具,负责管理依赖、生成配置文件及多平台构建。文章介绍了前端项目的构建流程、配置信息收集、依赖处理、asar 打包、附加资源准备、Electron 打包、代码签名、资源压缩、卸载程序生成、安装程序生成及最终安装包输出等环节。通过剖析 electron-builder 的原理,帮助开发者更好地理解和掌握跨端桌面应用的构建流程。
60 2
|
1月前
|
搜索推荐 Shell
解析排序算法:十大排序方法的工作原理与性能比较
解析排序算法:十大排序方法的工作原理与性能比较
47 9
|
1月前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
【10月更文挑战第1天】Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
117 9

推荐镜像

更多