• 深入了解 JavaScript 中的构造函数和对象创建


    深入了解 JavaScript 中的构造函数和对象创建

    在这篇博客中,我们将一起探讨 JavaScript 中的构造函数以及如何自己尝试定义一个 new函数

    构造函数:创建对象的魔法

    首先,让我们谈谈构造函数。在 JavaScript 中,构造函数是一种特殊类型的函数,用于创建新对象实例。构造函数通常需要通过 new 运算符来调用,这将创建一个全新的对象,并将其绑定到构造函数内的 this 上。

    const Person = function (name, age) {
      this.name = name;
      this.age = age;
    };
    
    const person = new Person("小明", 25);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在上面的示例中,我们创建了一个 Person 构造函数,用来初始化人物的名字和年龄属性。然后,我们使用 new 运算符创建了一个新的 person 对象,其中包含了这些属性。

    自定义 new 运算符

    但是,我们能否自己实现一个 new 运算符呢?

    const my_NewFun = function (constructorFn, ...args) {
      // 创建一个全新的对象,并将其原型指向构造函数的原型对象
      const obj = Object.create(constructorFn.prototype);
    
      // 使用构造函数以普通函数的方式调用,将新对象作为 this 传递进去
      const result = constructorFn.apply(obj, args);
    
      // 如果构造函数返回一个对象,则返回该对象;否则,返回创建的新对象
      return typeof result === "object" ? result : obj;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    这个自定义的 new 运算符模拟了 JavaScript 中 new 运算符的工作方式。

    使用自定义 new 运算符

    现在,让我们看看如何使用我们自己的 new 运算符,并将构造函数的原型方法继承到新对象中。

    const Person = function (name, age) {
      this.name = name;
      this.age = age;
    };
    
    Person.prototype.sing = function () {
      console.log("这个人正在唱歌!");
    };
    
    const person = my_NewFun(Person, "小红", 30);
    
    console.log(person); // Person { name: '小红', age: 30 }
    person.sing(); // 这个人正在唱歌!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这个示例中,我们使用自定义的 my_NewFun 函数创建了一个新的 person 对象,并成功继承了 Person 构造函数的原型方法。

    当使用自定义的 my_NewFun 函数来创建对象时,可以进一步扩展它,以满足不同的需求。

    1. 添加错误处理

    在自定义 new 函数中,你可以添加错误处理来捕获构造函数可能抛出的异常:

    const my_NewFun = function (constructorFn, ...args) {
      const obj = Object.create(constructorFn.prototype);
      const result = constructorFn.apply(obj, args);
    
      if (result && (typeof result === "object" || typeof result === "function")) {
        return result;
      }
    
      if (result === null) {
        return obj;
      }
    
      throw new Error(`构造函数返回了不支持的类型: ${typeof result}`);
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    这将处理构造函数可能返回的不同数据类型,如对象、函数或 null,并提供相应的处理方法。

    2. 继承链的深度

    你可以考虑在自定义 my_NewFun 函数中支持更深的原型链继承。如果构造函数继承自其他构造函数,你可以递归调用 my_NewFun 来处理这种情况:

    const my_NewFun = function (constructorFn, ...args) {
      const obj = Object.create(constructorFn.prototype);
      const result = constructorFn.apply(obj, args);
    
      if (result && (typeof result === "object" || typeof result === "function")) {
        return result;
      }
    
      if (result === null) {
        return obj;
      }
    
      if (typeof constructorFn.superConstructor === "function") {
        my_NewFun(constructorFn.superConstructor, ...args);
      }
    
      throw new Error(`构造函数返回了不支持的类型: ${typeof result}`);
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    这使你能够处理更复杂的继承链情况。

    3. 添加配置选项

    你可以考虑添加一些配置选项,以使自定义 new 函数更加灵活。例如,你可以允许在对象创建时传递一个配置对象,以自定义对象的行为。

    const my_NewFun = function (constructorFn, ...args) {
      const options = args.pop(); // 最后一个是配置对象
      const obj = Object.create(constructorFn.prototype);
      const result = constructorFn.apply(obj, args);
    
      // 使用自定义配置
      if (options) {
        // ...
      }
    
      return result || obj;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    通过这些扩展,,使自定义的 new 函数更加灵活。

  • 相关阅读:
    Python笔记 · Python语言的“动态性”
    使用 Hugging Face Transformer 创建 BERT 嵌入
    MyBatisPlus笔记
    leetcode891:子序列宽度之和
    论文复现|Panoptic Deeplab(全景分割PyTorch)
    【直播预告】相机模型与标定——Real world超级公开课
    金仓数据库 KingbaseES V8.3至V8.6迁移最佳实践(2. KingbaseES V8.3和 V8.6 兼容性)
    Python + Django4 搭建个人博客(二):准备开发环境
    【PHP】为什么2022年我还建议你学一下PHP
    Ubuntu22.04_如何调试ROS2_humble的源代码
  • 原文地址:https://blog.csdn.net/m0_66492535/article/details/133829281