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

【前端】JavaScript 中的创建对象模式要点


在这里插入图片描述

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

文章目录

  • 💯前言
  • 💯对象属性值中的引号规则
  • 💯对象属性换行与尾随逗号的使用
  • 💯工厂模式:灵活高效的对象创建
  • 💯自定义构造函数:通过 `new` 创建对象
  • 💯`instanceof` 的作用与原型链
    • 工厂模式的 `instanceof`
    • 自定义构造函数的 `instanceof`
  • 💯 工厂模式与自定义构造函数的对比
  • 💯小结


在这里插入图片描述


💯前言

  • JavaScript 的研究和应用中,深入理解对象的创建方式至关重要。无论是初学者还是经验丰富的开发者,JavaScript工厂模式自定义构造函数模式都是需要全面掌握的知识点。在本文中,我们将详细探讨这些模式,包括它们的使用方式、各自的优劣、以及在特定场景中的适用性。通过对这些模式的深刻理解,读者可以更好地掌握 JavaScript 中的面向对象编程技术,从而撰写出具备高度扩展性可维护性的代码。
    JavaScript在这里插入图片描述

💯对象属性值中的引号规则

在这里插入图片描述
首先,需要理解如何在 JavaScript 中正确地为对象属性赋值。对象的属性值可以有多种类型,其中字符串类型的值必须用引号包裹(可以是单引号'或双引号"),而其他类型的值,如数字布尔值等,则无需引号。这种区别对于代码的可读性和减少错误尤为重要,尤其在复杂的应用程序或大型项目中,保持代码风格的一致性是提高开发效率可维护性的重要因素。

例如:

var obj = {
    name: 'Alice', // 字符串类型,必须用引号
    age: 25,       // 数字类型,不需要引号
    isStudent: true // 布尔值,不需要引号
};

在上述代码中,name 属性的值是字符串,因此必须用引号包裹,而 ageisStudent 则是数字和布尔类型,因此没有使用引号。这些细节对于避免低级语法错误、提高代码一致性和可读性具有重要意义。同时,这种约定也有助于团队成员之间的协作,确保代码风格统一,使得代码更容易被理解和维护。


💯对象属性换行与尾随逗号的使用

在这里插入图片描述
在编写对象时,经常会遇到需要添加多个属性的情况。为了提高代码的可读性,通常会将每个属性分行书写,并用逗号进行分隔。在这种情况下,最后一个属性的后面可以选择加逗号,也可以不加逗号,在现代 JavaScript 中这两种方式都是合法的。这种灵活性不仅使代码更加清晰,同时也在修改对象时减少了可能的错误。

例如:

var student = {
    name: 'Bob',
    age: 22,
    gender: 'Male', // 最后的逗号是可选的
};

这种书写方式被称为**“尾随逗号”,它的主要优势在于当需要为对象添加新属性时,可以避免对之前最后一行的属性进行修改,从而降低修改引入错误的风险。在大型代码库或复杂的对象结构中,使用尾随逗号可以显著减少人为失误,尤其是在多人协作的开发环境下**,这种书写规范可以让代码的维护更加轻松和高效


💯工厂模式:灵活高效的对象创建

在这里插入图片描述
在 JavaScript 中,工厂模式是一种通过函数创建并返回对象的设计模式。工厂模式的主要优势在于可以灵活地创建对象,而不必依赖 new 关键字。这种模式特别适合需要根据参数动态生成不同类型对象的场景,极大地提高了代码的复用性和灵活性。它使得我们能够在函数内部决定返回什么样的对象,而不需要拘泥于特定的构造函数。

例如:

function createStudent(name, age, sex) {
    var obj = new Object();
    obj.name = name;
    obj.age = age;
    obj.sex = sex;
    obj.speak = function () {
        console.log('我要学习, 学习使我快乐, 学习让我成长!');
    };
    return obj;
}

var student1 = createStudent('小明', 18, 'Male');

在上述例子中,createStudent 是一个工厂函数,它创建了一个新的对象 obj,根据传入的参数为对象赋值,并最终返回这个对象。工厂模式的一个重要特征就是它不需要 new 关键字来调用,而是直接返回新对象。这种灵活性使得工厂模式在处理创建结构相似但配置不同的对象时显得尤为便利,尤其在需要根据不同输入生成具有不同配置的对象时,工厂模式提供了极大的便利。

此外,工厂模式还可以通过封装复杂逻辑来简化对象的创建过程,使代码更加简洁并且易于测试。例如,如果我们需要创建不同类型的学生对象,可以根据传递的 type 参数返回不同的对象,而无需为每种类型的对象定义不同的构造函数。


💯自定义构造函数:通过 new 创建对象

在这里插入图片描述
与工厂模式不同,自定义构造函数依赖于 new 关键字来创建对象。构造函数的定义方式与普通函数类似,但通常第一个字母大写,以示区分。构造函数通过使用 this 关键字来定义对象的属性和方法,属性和方法都会绑定到新创建的实例上。

例如:

function Student(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.speak = function () {
        console.log('我要学习, 学习使我快乐, 学习让我成长! 我叫 ' + this.name);
    };
}

var student2 = new Student('张三', 20, 'Male');

在这个例子中,Student 是一个构造函数,使用 new Student('张三', 20, 'Male') 可以创建一个新的实例 student2。构造函数的核心特征是它通过 new 关键字来调用,this 关键字指向新创建的对象实例,因此可以通过 this 来为对象添加属性和方法。通过 new 关键字创建的对象不仅可以确保独立实例之间的隔离性,同时能够复用构造函数定义的逻辑。

构造函数的一个显著优点是它可以结合 prototype 实现方法的共享。将方法定义在构造函数的原型对象上,而不是在构造函数内部定义,可以避免每个实例都创建一个独立的方法,这样既节省了内存,又保持了一致性。例如,可以将 speak 方法放在 Student.prototype 上,使得所有实例共享同一个 speak 方法,这在需要大量创建对象的场景中尤为重要。


💯instanceof 的作用与原型链

在这里插入图片描述
在 JavaScript 中,instanceof 用于检查一个对象是否为某个构造函数的实例。instanceof 的原理是沿着对象的原型链(prototype chain)进行查找,如果对象的原型链中存在与构造函数的 prototype 属性相等的原型,instanceof 就会返回 true。这使得 instanceof 成为实现继承和检查对象类型的重要工具。

例如:

console.log(student2 instanceof Student); // true
console.log(student2 instanceof Object);  // true

在上述例子中,student2 是通过 Student 构造函数创建的,因此 student2 instanceof Studenttrue。由于所有对象的原型链最终都会指向 Object.prototype,因此 student2 instanceof Object 也为 true。这种类型检查方法对于确保代码的可靠性和健壮性非常有效,特别是在构建复杂的对象体系结构时。


工厂模式的 instanceof

通过工厂模式创建的对象,因为没有通过 new 绑定到特定的构造函数,因此这些对象与工厂函数之间没有直接的原型链关系。因此,使用 instanceof 检测工厂模式创建的对象时,结果通常不会与工厂函数关联。

例如:

function createStudent(name, age, sex) {
    var obj = new Object(); //new 构造函数();
    obj.name = name;
    obj.age = age;
    obj.sex = sex;
    obj.speak = function () {
        console.log('我要学习,学习使我快乐,学习让我成长!');
    }
    return obj;
}
var stu1 = createStudent('小明', 99, 'Man');

console.log(stu1 instanceof createStudent); // false
console.log(stu1 instanceof Object);        // true

在这里插入图片描述

在上述代码中,stu1 是通过工厂函数创建的普通对象,但它并没有与 createStudent 函数建立任何原型链上的关联,因此 stu1 instanceof createStudent 返回 false。然而,由于所有通过对象字面量或 new Object() 创建的对象最终都是 Object 的实例,因此 stu1 instanceof Object 返回 true。这表明,工厂模式创建的对象在类型检查方面是相对弱化的,而通过构造函数模式创建的对象则具有更强的类型关联。

这种差异意味着,如果需要通过 instanceof 来判断某个对象是否是某个类型的实例,那么工厂模式并不适合,因为工厂函数返回的对象与它们没有直接的原型链关系。而构造函数模式通过 prototype 属性使对象与构造函数保持了联系,因此 instanceof 在这种模式下可以提供可靠的类型检查。


自定义构造函数的 instanceof

通过自定义构造函数创建的对象能够可靠地通过 instanceof 检查。这是因为通过 new 关键字调用构造函数时,JavaScript 会自动将新创建的对象的原型(__proto__)指向构造函数的 prototype,从而形成了正确的原型链关系。

例如:

function Student(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.speak = function () {
        console.log('我要学习, 学习使我快乐, 学习让我成长! 我叫 ' + this.name);
    };
}

var stu3 = new Student('张三', 18, 'Man');

console.log(stu3 instanceof Student); // true
console.log(stu3 instanceof Object);  // true

在这里插入图片描述

在上述例子中,stu3 是通过 Student 构造函数创建的对象,因此 stu3 instanceof Studenttrue。这表明 stu3 的原型链中包含 Student.prototype。同时,stu3 也是 Object 的实例,因为所有的对象最终都继承自 Object,因此 stu3 instanceof Object 也为 true

这种可靠的原型链关系使得通过构造函数模式创建的对象能够进行精确的类型判断,尤其是在复杂的应用场景中,这种机制对于确保对象的正确性和类型安全性尤为重要。它使得构造函数模式在需要进行严格类型检查和继承的场景中显得更为适用。


💯 工厂模式与自定义构造函数的对比

在这里插入图片描述

特性工厂模式 (createStudent)自定义构造函数 (Student)
instanceof 检测结果falsetrue
对象与函数的关联没有关联,返回普通对象对象与构造函数的 prototype 有关联
使用方式普通函数调用,返回一个独立对象必须使用 new 关键字
原型链机制与工厂函数无关实例通过原型链指向构造函数的 prototype
灵活性可以动态返回不同类型的对象只能返回固定的构造对象

在实际开发中,工厂模式适用于需要灵活创建不同类型对象的场景,而自定义构造函数模式则更适合于需要共享方法和属性的对象创建场景。构造函数模式通过prototype实现了方法的共享,因而在需要创建大量相似对象时更为高效,而工厂模式由于其动态特性则在处理变化较多的对象结构时表现得更好。在某些复杂的场景中,两者可以结合使用,以充分发挥它们各自的优势。例如,通过工厂函数来包装构造函数,从而在创建对象时既能享受构造函数的性能优势,又能够保持工厂模式的灵活性


💯小结

  • 在这里插入图片描述
    通过这篇文章,我们深入探讨了 JavaScript工厂模式自定义构造函数模式的不同特性与适用场景。工厂模式提供了一种灵活的方式来创建对象,尤其适用于动态需求的场景,而自定义构造函数结合new关键字,则让我们能够通过原型链共享方法,非常适合需要大量相似对象的场景。掌握这些差异有助于在实际开发中灵活运用,选择最适合的模式,从而编写出更加高效可维护的代码。
    除了深入理解 JavaScript原型链机制,理解 ES6 引入的class语法也是非常重要的。虽然class本质上是基于原型的语法糖,但它提供了一种更具表现力且易于使用的方式来定义对象和继承关系。通过结合工厂模式自定义构造函数class语法,开发者能够更灵活地应对多样的编程需求,编写出结构合理且便于扩展的代码。对这些模式及其底层机制的深刻理解,将使你在 JavaScript 编程的道路上更具信心并能应对各种复杂挑战

在这里插入图片描述



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

相关文章:

  • macOS运行amd64的镜像
  • Linux条件变量线程池详解
  • TypeScript和JavaScript的区别
  • Milvus×OPPO:如何构建更懂你的大模型助手
  • BWO-CNN-BiGRU-Attention白鲸优化算法优化卷积神经网络结合双向门控循环单元时间序列预测,含优化前后对比
  • 红队/白帽必经之路(16)——如何用Metasploit 在边路进行信息刺探及爆破登录[既然是红队,那就对自己狠一点!!!]
  • java 在方法里,开一个线程,如果报错,不影响原来的方法
  • spring boot有哪些不足之处?
  • NaviveUI框架的使用 ——安装与引入(图标安装与引入)
  • 使用PyPDF2工具加载pdf文件数据
  • Linux C/C++编程之动态库
  • 使用Grafana K6来测测你的系统负载能力
  • 前端禁用 页面复制粘贴
  • SpringBoot 构建在线家具商城:系统设计与技术实现
  • element-ui的下拉框报错:Cannot read properties of null (reading ‘disabled‘)
  • Qt入门6——Qt窗口
  • python学习笔记13 python中的函数(下)
  • 40分钟学 Go 语言高并发:【实战课程】性能瓶颈分析与优化实战
  • 基于Matlab合成孔径雷达(SAR)回波信号建模与多指标质量评估
  • nodejs建立TCP服务器端和TCP客户端之间的连接
  • VisionPro、Mac、IPad、如何连接Windows 文件互传
  • YOLOv8-ultralytics-8.2.103部分代码阅读笔记-loss.py
  • 深入探索 CnosDB 可观测性最佳实践:Metrics
  • 架构师:Dubbo 服务请求失败处理的实践指南
  • 蓝桥杯真题——砍竹子(C语言)
  • 如何在Spark中使用gbdt模型分布式预测