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

【前端】深度解析 JavaScript 中的 new 关键字与构造函数


在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: 前端

文章目录

  • 💯前言
  • 💯构造函数的核心特性
  • 💯`new` 关键字的执行机制
  • 💯实例代码与详细解析
    • 代码示例
    • 代码逐步解析
  • 💯`new` 的内部执行模拟
    • 执行过程的详细解析
  • 💯代码优化:共享方法的实现
    • 优化后的代码
    • 优化优势
  • 💯深入理解:实现 `new` 的功能
    • `myNew` 的实现
    • 实现逻辑
  • 💯小结


在这里插入图片描述


💯前言

  • JavaScript面向对象编程中,构造函数与 new 关键字共同构成了对象创建机制的核心构造函数是一种特殊设计的函数,其主要作用在于初始化对象属性并定义行为逻辑,而 new 关键字则是对这一过程的进一步抽象,为对象的实例化提供了便捷的方式。构造函数不仅是对象创建的基础,也是原型链继承的重要组成部分。通过结合 new 关键字,开发者能够更高效地生成具有统一特征的对象实例,从而提高代码的复用性可维护性
    JavaScript在这里插入图片描述

💯构造函数的核心特性

  1. 创建类的统一性:构造函数通常用于生成具有相同结构的对象,其命名遵循大写首字母的惯例,以便于与普通函数区分。
  2. 参数化初始化:构造函数允许开发者通过参数为实例对象赋予特定的初始值。
  3. new 配套使用:构造函数在没有 new 的辅助时,其作用极为有限,只有通过 new 执行时,才能完成实例化过程。

💯new 关键字的执行机制

new 执行的四步操作:

  1. 创建一个空对象,作为将要返回的实例。
  2. 将空对象的原型指向构造函数的 prototype 属性。
  3. 将构造函数中的 this 指向该对象。
  4. 执行构造函数的代码,完成对象初始化。
    new 操作符的支持下,构造函数得以实现以下功能:
  1. 创建空对象:new 首先创建一个空对象,作为即将返回的实例。
  2. 链接原型链:将新对象的原型指向构造函数的 prototype 属性,从而实现原型继承。
  3. 绑定构造函数上下文:将构造函数内部的 this 绑定到新创建的对象,确保属性和方法正确赋值。
  4. 执行构造函数逻辑:运行构造函数的主体代码,以完成对象的初始化。

通过 new,我们不仅可以高效地实例化对象,还可以确保新对象正确继承构造函数的功能。


💯实例代码与详细解析

以下代码示例展示了如何使用构造函数和 new 关键字创建对象:


代码示例

<body>
    <script>
        function Cat(name, age) {
            this.name = name; // 定义实例的 name 属性
            this.age = age;   // 定义实例的 age 属性
            this.speak = function() { // 为实例定义方法 speak
                console.log('我是' + this.name + '喵喵喵');
            };
        }

        var cat1 = new Cat('橘子', 1);
    </script>
</body>

代码逐步解析

  1. 构造函数的定义

    function Cat(name, age) {
        this.name = name; // 将 name 属性赋值给新对象
        this.age = age;   // 将 age 属性赋值给新对象
        this.speak = function() { // 定义实例的方法 speak
            console.log('我是' + this.name + '喵喵喵');
        };
    }
    
    • Cat 是构造函数,其功能在于初始化对象的 nameage 属性。
    • 使用 this 关键字确保属性和方法绑定到实例对象。
  2. 实例化对象

    var cat1 = new Cat('橘子', 1);
    
    • 通过 new Cat('橘子', 1) 创建对象 cat1,同时执行了 Cat 函数。
    • cat1 是包含属性 nameage 以及方法 speak 的实例。
  3. 调用实例方法

    cat1.speak();
    // 输出:我是橘子喵喵喵
    
    • 通过实例调用 speak 方法,能够正确输出绑定的 name 属性值。

💯new 的内部执行模拟

为了更直观地理解 new 的执行机制,以下代码对其内部过程进行了模拟:

function Cat(name, age) {
    // 模拟 new 的第一步:创建一个空对象
    // var Obj = new Object();
	// 第二步
    // 第三步:绑定 this 到新对象
    // this => Obj

    this.name = name;
    this.age = age;
    this.speak = function() {
        console.log('我是' + this.name + '喵喵喵');
    };

    // 第四步:返回新对象(隐式返回)
    // return Obj;
}

var cat1 = new Cat('橘子', 1);

执行过程的详细解析

  1. 创建新对象:var Obj = new Object() 隐式创建了一个空对象。
  2. 链接原型链:Obj.__proto__ = Cat.prototype 将空对象的原型指向构造函数的 prototype 属性。
  3. 绑定上下文:this 被绑定到新对象 Obj,使构造函数内部的属性和方法被正确初始化。
  4. 返回新对象:若构造函数无显式返回值,new 操作会隐式返回步骤 1 中创建的对象。

这种过程解释了 new 如何将对象实例化的逻辑分解为步骤。


💯代码优化:共享方法的实现

上述代码中,speak 方法是直接定义在每个实例上的,这种方式会导致不必要的内存浪费。为了优化,我们可以将方法定义在构造函数的 prototype 上,使所有实例共享相同的方法。


优化后的代码

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

Cat.prototype.speak = function() {
    console.log('我是' + this.name + '喵喵喵');
};

var cat1 = new Cat('橘子', 1);
cat1.speak(); // 输出:我是橘子喵喵喵

优化优势

  1. 内存效率更高:所有实例共享 speak 方法,不再为每个实例重复创建方法。
  2. 代码更简洁:方法逻辑集中在原型中,便于维护与扩展。

💯深入理解:实现 new 的功能

为了深入理解 new 的工作原理,我们可以尝试手动实现一个 myNew 方法,模拟其核心功能:


myNew 的实现

function myNew(constructor, ...args) {
    // 1. 创建一个空对象
    let obj = {};

    // 2. 将新对象的原型指向构造函数的 prototype
    obj.__proto__ = constructor.prototype;

    // 3. 执行构造函数,将 this 绑定到新对象
    constructor.apply(obj, args);

    // 4. 返回新对象
    return obj;
}

// 测试 myNew
function Cat(name, age) {
    this.name = name;
    this.age = age;
    this.speak = function() {
        console.log('我是' + this.name + '喵喵喵');
    };
}

const cat2 = myNew(Cat, '小白', 2);
cat2.speak(); // 输出:我是小白喵喵喵

实现逻辑

  1. 对象创建:let obj = {} 创建一个空对象作为实例。
  2. 链接原型:通过 obj.__proto__ = constructor.prototype 实现继承。
  3. 执行构造函数:利用 constructor.apply(obj, args) 将构造函数的上下文绑定到新对象。
  4. 返回实例:手动返回经过初始化的对象实例。

这种实现方式明确揭示了 new 操作的核心机制。


💯小结

本文从基础概念到内部机制,全方位解析了 JavaScript 中的构造函数与 new 关键字,并探讨了其优化与扩展实现。

  1. new 的四步核心机制:创建对象、链接原型、绑定上下文、执行构造逻辑。
  2. 构造函数的设计:通过参数化和 this 实现对象属性和方法的灵活定义。
  3. 优化代码结构:通过原型链共享方法提升内存效率。
  4. 扩展实践:自定义 myNew 方法,以加深对语言特性的理解。

通过对这些知识点的深入探讨,我们不仅掌握了 JavaScript 对象创建的原理,还理解了如何优化代码结构,并从底层逻辑中汲取灵感,为实际开发提供指导。如果对本文内容有进一步的疑问或启发,欢迎与我继续交流探讨。


在这里插入图片描述


在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述


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

相关文章:

  • 15个学习Python 的编程游戏网站
  • netplan apply报错No module named ‘netifaces‘
  • ubuntu20下编译linux1.0 (part1)
  • 551 灌溉
  • 设计模式-结构型-组合模式
  • C语言的语法
  • 【ETCD】【源码阅读】configurePeerListeners() 函数解析
  • 数据结构——哈夫曼树
  • 【电控笔记z46】非线性磁链笔记
  • Spring Boot 3.3.4 升级导致 Logback 之前回滚策略配置不兼容问题解决
  • AI智能体Prompt预设词指令大全+GPTs应用使用
  • Vue了解
  • 使用PXE+Kickstart无人值守安装Linux操作系统
  • 正则表达式去除文本中括号()<>[]里的内容
  • BurpSuite-8(FakeIP与爬虫审计)
  • 工业—使用Flink处理Kafka中的数据_EnvironmentData1
  • 音视频入门基础:MPEG2-TS专题(12)—— FFmpeg源码中,使用Section把各个transport packet组合起来的实现
  • Oracle之表空间迁移
  • 爽解报错:/bin/bash^M: bad interpreter: No such file or directory
  • es 3期 第13节-多条件组合查询实战运用
  • mvn test 失败,单独运行单元测试成功
  • Mysql | 尚硅谷 | 第04章_运算符
  • RabbitMQ 实现分组消费满足服务器集群部署
  • SpringCloud提供的多维度解决方案:构建高效微服务生态系统
  • QT 12月5日练习
  • 11.12[CQU JAVEE_EXP3][JAVA WEB]3h速成JAVA WEB;DE启动Tomcat的各种BUG;GIT