当前位置: 首页 > article >正文

javascript中new操作符的工作原理

在 JavaScript 中,new 操作符用于创建对象的实例。它可以让我们通过构造函数创建一个新的对象,并初始化该对象的属性和方法。尽管 new 操作符的使用很常见,但它在背后实际进行了几个步骤。下面详细解释 new 操作符具体做了哪些事情。

new 操作符的执行过程

当我们使用 new 来调用一个构造函数时,JavaScript 会自动执行以下步骤:

  1. 创建一个新的空对象

    • 创建一个新的对象(我们可以称它为 newObj),这个对象继承了构造函数的 prototype 属性。
    • newObj.__proto__ = Constructor.prototype
  2. this 绑定到新创建的对象上

    • 构造函数中的 this 会被绑定到新创建的对象(即 newObj)上。
    • 这样,在构造函数中定义的属性和方法就会被添加到新对象上。
  3. 执行构造函数的代码

    • 构造函数会被执行,并且 this 现在指向 newObj。构造函数内部可以为新对象添加属性或方法。
  4. 返回新对象

    • 如果构造函数显式返回一个对象,那么返回这个对象。
    • 如果构造函数没有显式返回对象,则默认返回创建的 newObj

示例

通过一个简单的例子来说明 new 的工作原理:

function Person(name, age) {
  this.name = name;
  this.age = age;
  this.sayHello = function() {
    console.log('Hello, my name is ' + this.name);
  };
}

const person1 = new Person('Alice', 25);
console.log(person1.name);  // 输出: Alice
console.log(person1.age);   // 输出: 25
person1.sayHello();         // 输出: Hello, my name is Alice

在这个例子中,我们使用 new 来创建 Person 对象的实例 person1,这个对象拥有 nameage 属性,并且可以调用 sayHello 方法。

new 操作符的执行细节

让我们逐步看一下当执行 new Person('Alice', 25) 时,发生了什么:

  1. 创建一个新的空对象

    • 一个空对象 newObj 被创建,它的 __proto__ 指向 Person.prototype
    newObj = Object.create(Person.prototype);
    
  2. this 绑定到新对象上

    • 调用构造函数 Person 时,this 被绑定为 newObj,并且构造函数内部的 this.namethis.age 被赋值。
    Person.call(newObj, 'Alice', 25);
    
  3. 执行构造函数的代码

    • 构造函数内部的代码运行,为 newObj 添加了 nameage 属性以及 sayHello 方法。
  4. 返回新对象

    • 因为构造函数没有显式返回对象,所以默认返回 newObj

最终结果是,一个拥有 nameage 属性的对象 person1 被创建,并且继承了 Person.prototype 的所有属性和方法。

new 操作符的步骤模拟

我们可以通过手动模拟 new 操作符来理解它的内部工作原理。下面是一个简化的 new 的实现:

function myNew(constructor, ...args) {
  // 1. 创建一个新的空对象
  const obj = Object.create(constructor.prototype);

  // 2. 将 this 绑定到新的对象并执行构造函数
  const result = constructor.apply(obj, args);

  // 3. 如果构造函数返回的是一个对象,则返回该对象,否则返回新创建的对象
  return result instanceof Object ? result : obj;
}

function Person(name, age) {
  this.name = name;
  this.age = age;
}

const person1 = myNew(Person, 'Alice', 25);
console.log(person1.name);  // 输出: Alice
console.log(person1.age);   // 输出: 25

在上面的代码中,myNew 函数模拟了 new 的基本行为,包括创建对象、绑定 this、执行构造函数和返回新对象。

new 操作符中的返回值

  • 如果构造函数显式返回一个对象,则 new 操作符返回该对象。
  • 如果构造函数没有返回对象,new 操作符将返回创建的对象。

例如:

function Person(name) {
  this.name = name;
  return { customObject: true };
}

const person1 = new Person('Alice');
console.log(person1);  // 输出: { customObject: true }

function Animal(name) {
  this.name = name;
  // 没有显式返回值
}

const animal1 = new Animal('Tiger');
console.log(animal1);  // 输出: Animal { name: 'Tiger' }

Person 的例子中,构造函数返回了一个对象 { customObject: true },因此 new 操作符返回了这个对象,而不是默认的新对象。

Animal 的例子中,构造函数没有显式返回对象,new 操作符会返回 new Animal() 创建的实例对象。

new 的使用场景

new 操作符最常用于构造函数模式或类来创建对象的实例。常见场景包括:

  1. 创建类的实例

    • JavaScript 中的类定义使用 class 语法可以通过 new 来创建实例。
    class Person {
      constructor(name) {
        this.name = name;
      }
    }
    
    const person1 = new Person('Alice');
    console.log(person1.name); // 输出: Alice
    
  2. 使用构造函数创建对象

    • 除了 class 语法,传统的构造函数模式也是通过 new 来创建实例。
    function Car(model) {
      this.model = model;
    }
    
    const car1 = new Car('Toyota');
    console.log(car1.model); // 输出: Toyota
    
  3. 内置对象的实例化

    • JavaScript 的一些内置对象也需要通过 new 来创建实例,如 DateRegExpArray 等。
    const today = new Date();
    console.log(today); // 输出当前日期和时间
    

总结

new 操作符在 JavaScript 中用于创建对象的实例,它在背后执行了以下几步:

  1. 创建一个新的空对象并将其原型指向构造函数的 prototype
  2. 将构造函数的 this 绑定到新对象上。
  3. 执行构造函数的代码,初始化新对象的属性。
  4. 返回这个新对象(如果构造函数返回对象,则返回该对象)。

通过 new 操作符,我们可以轻松创建复杂对象,并且通过原型链继承共享方法和属性。


http://www.kler.cn/a/320856.html

相关文章:

  • 【windows笔记】08-Windows中的各种快捷方式、符号链接、目录联接、硬链接的区别和使用方法
  • 跟我学C++中级篇——RAII
  • 微信小程序 https://thirdwx.qlogo.cn 不在以下 downloadFile 合法域名列表中
  • 【目标检测】用YOLOv8-Segment训练语义分割数据集(保姆级教学)
  • 计算机网络 (3)计算机网络的性能
  • 前后端、网关、协议方面补充
  • 使用lodash库实现防抖和节流
  • Easy Excel从入门到精通!!!
  • pg入门11-pg中的publications是什么
  • SpringBoot整合Lombok插件与使用说明
  • 微信小程序showLoading ,showToast ,hideLoading连续调用出现showLoading 不关闭的情况记录
  • SpringDoc OpenApi学习笔记
  • GO Ants 学习
  • C++——将数组a[5]={-1,2,9,-5,7}中小于0的元素置成0。并将其结果输出(要求:用数组名作为函数的参数来实现)
  • C++游戏
  • Linux部署python web项目Flask + gunicorn + nginx
  • 《经典图论算法》约翰逊算法(Johnson)
  • 前端插件开发用什么技术比较好,用来程序自动化下载
  • TypeScript 设计模式之【单例模式】
  • [每日一练]修复表中的名字
  • Dependency Check:一款针对应用程序依赖组件的安全检测工具
  • ACM MM24 | Hi3D: 3D生成领域再突破!新视角生成和高分辨率生成双SOTA(复旦智象等)
  • Java 编码系列:异常处理与自定义异常
  • 一些广泛认可的编程工具,在不同的方面帮助我们提升效率
  • 使用cmd命令窗口操作mongodb
  • Scikit-LearnTensorFlow机器学习实用指南(三):一个完整的机器学习项目【下】