JavaScript对象设计哲学:八种模式塑造高效代码

在这里插入图片描述

🔥 个人主页:空白诗

在这里插入图片描述

文章目录

    • 一、引言 🚀
    • 二、Object 构造函数 🧱
      • 📌 基本用法
      • 📌 重要性
      • 📌 实际应用案例
    • 三、对象字面量 📘
      • 📌 定义属性
      • 📌 定义方法
      • 📌 属性特性
      • 📌 注意事项
    • 四、Object.create() 🔗
      • 📌 基本用法
      • 📌 关键点
      • 📌 优点
      • 📌 注意事项
    • 五、类(ES6)🏫
      • 📌 基本结构
      • 📌 关键特性
      • 📌 重要概念
    • 六、工厂模式 🏭
      • 📌 基本实现
      • 📌 优势
      • 📌 应用场景
      • 📌 注意事项
    • 七、构造函数模式 🔨
      • 📌 基本用法
      • 📌 核心特点
      • 📌 优缺点
      • 📌 解决方法重定义问题
    • 八、原型模式 🧬
      • 📌 基础概念
      • 📌 核心原理
      • 📌 优点
      • 📌 缺点
      • 📌 使用建议
    • 九、组合模式 🌈
      • 📌 示例解析
      • 📌 组合模式的优势
      • 📌 应用场景
    • 十、总结 🎯
    • 🔗 相关知识


在这里插入图片描述


一、引言 🚀

JavaScript编程的广阔天地里,对象作为构建复杂应用的基石,其创建与管理是每个开发者必须掌握的核心技能。本文将带你深入探索对象创建的八大途径,从经典到现代,全方位覆盖,助你灵活运用,打造健壮高效的代码结构。

对象JavaScript中一种复合数据类型,能够存储多个不同数据类型的值。它们不仅存储数据,还封装了方法,即可以直接在对象上执行的功能。了解多种创建对象的方法,对于编写清晰、可维护的代码至关重要。接下来,让我们一一揭开这些方法的神秘面纱。🔍


二、Object 构造函数 🧱

Object构造函数是JavaScript中最基础的对象创建方式,虽然在日常开发中不如对象字面量那样频繁使用,但它对于深入理解JavaScript的对象模型和原型链机制具有重要意义。

📌 基本用法

const obj = new Object(); // 创建一个空对象
obj.key = 'value'; // 动态添加属性
console.log(obj); // 输出:{ key: 'value' }

📌 重要性

  1. 理解对象本质:通过Object构造函数创建对象,可以帮助开发者从底层认识对象如何在JavaScript中被构造,进而深入理解原型链的概念。

  2. 动态性展示:上面的示例展示了JavaScript对象的动态性,即可以在对象创建后随时添加或修改属性和方法。

  3. 与其他方法对比:与对象字面量相比,Object构造函数显得冗余,但在某些特定场景下,如通过函数动态生成对象时,它展现了灵活性。

  4. 与其他构造函数的关系:所有JavaScript的构造函数(包括自定义构造函数)在原型链的顶端都指向Object.prototype,这意味着所有对象最终都是Object的实例,凸显了Object构造函数的基础地位。

📌 实际应用案例

在某些高级应用中,如需要基于条件创建具有不同属性的对象时,Object构造函数配合逻辑判断可以提供灵活性。

```javascript
/**
 * 创建一个具有条件属性的对象。
 * 
 * 根据传入的isAdmin参数决定对象是否包含管理员专有属性。
 * 
 * @param {boolean} isAdmin - 一个布尔值,指示用户是否为管理员。
 * @returns {object} 返回一个对象,包含commonProperty和可选的adminProperty。
 */
function createCustomObject(isAdmin) {
  // 使用Object构造函数创建一个新的空对象
  const obj = new Object();
  
  // 添加所有对象共有的属性
  obj.commonProperty = 'sharedValue';
  
  // 根据isAdmin的值决定是否添加管理员专有属性
  if (isAdmin) {
    obj.adminProperty = 'adminOnlyValue';
  }
  
  // 返回配置好的对象
  return obj;
}

// 调用函数并传入true,表示创建一个管理员对象
const userObj = createCustomObject(true);

// 打印输出用户对象,根据isAdmin参数,可能包含adminProperty
console.log(userObj); // 输出为:{ commonProperty: 'sharedValue', adminProperty: 'adminOnlyValue' }

尽管直接使用对象字面量通常更为简便,理解并掌握Object构造函数对于深化JavaScript对象知识体系、特别是在处理更复杂的对象创建逻辑时,是不可或缺的一环。它不仅体现了JavaScript的动态性,也是通往更高级对象操作和理解原型继承机制的基石。


三、对象字面量 📘

对象字面量是JavaScript中创建单个对象的一种非常直接且简洁的方法。它允许你通过一对花括号 {} 来直观地定义一个对象的属性和方法。这种方式因其简洁性和易读性而被广泛使用。下面是关于对象字面量的一些关键点和扩展说明:

📌 定义属性

  • 直接赋值:如示例所示,你可以直接在花括号内键值对的形式定义属性。键(即属性名)后面跟一个冒号,然后是该属性的值。
const person = {
  name: 'Alice', // 字符串属性
  age: 30,       // 数字属性
};

📌 定义方法

  • 函数作为值:对象的属性也可以是一个函数,这种情况下通常称为“方法”。定义方法时,只需像定义普通属性那样给出名称,并将其值设置为一个函数表达式。
greet: function() {
  console.log('Hello, my name is ' + this.name);
}
  • 简写方法语法ES6引入了更简洁的方法定义方式,允许你省略function关键字和冒号。
const person = {
  name: 'Alice',
  age: 30,
  greet() { // 简写方法定义
    console.log(`Hello, my name is ${this.name}`);
  }
};

访问和修改属性

  • 点符号访问:可以通过点符号(.)访问对象的属性和方法。
console.log(person.name); // 访问属性
person.greet();           // 调用方法
  • 方括号 [ ]:对于动态属性名或包含特殊字符的属性名,可以使用方括号表示法。
const key = 'name';
console.log(person[key]); // 动态访问属性

📌 属性特性

  • getter 和 setter:可以定义访问器属性(gettersetter),用于在获取或设置属性值时执行某些操作。
const person = {
  _name: 'Alice', // 使用下划线前缀表示私有属性是一种约定
  get name() { // getter
    return this._name;
  },
  set name(value) { // setter
    if (value.trim() === '') {
      throw new Error('Name cannot be empty');
    }
    this._name = value;
  }
};

person.name = ' Bob '; // 自动去除首尾空格
console.log(person.name); // 输出:Bob

📌 注意事项

  • this关键字:在对象方法中,this关键字指向调用该方法的对象。但在箭头函数中,this由其定义时的上下文决定,而非调用时的上下文,因此箭头函数通常不用于定义对象的方法。

通过对象字面量,你可以快速构造出结构清晰、易于理解的对象结构,是JavaScript面向对象编程的基础之一。


四、Object.create() 🔗

Object.create() 方法是ECMAScript标准中提供的一种高级对象创建方式,它直接体现了JavaScript的原型继承机制。这个方法允许你以一个对象作为原型(prototype),创建一个新对象,新对象将继承原型的所有可枚举属性和方法。这种方式非常适合构建复杂的继承结构,尤其是在需要明确控制原型链的情况下。

📌 基本用法

const personProto = {
  greet: function() {
    console.log('Hello, I am a person.');
  }
};

const john = Object.create(personProto);
john.name = 'John Doe';
john.greet(); // 输出:Hello, I am a person.

📌 关键点

  1. 原型对象 (personProto): 这是新创建对象的原型。新对象将从这个对象继承属性和方法。在这个例子中,personProto有一个greet方法。

  2. 新对象创建 (john): 通过调用 Object.create(personProto) 创建了一个新对象,并将其原型链的顶部设置为personProto。这意味着john对象可以访问personProto上定义的所有属性和方法。

  3. 属性添加 (john.name): 我们可以直接在新对象上添加属性,而不会影响原型对象。这里给john添加了一个name属性。

  4. 方法调用 (john.greet()): 尽管greet方法不是直接定义在john上,但由于原型链的存在,john可以访问并调用它。

📌 优点

  • 原型隔离:可以避免直接修改原型链上的对象,保持原型的纯净性。
  • 灵活性:能够创建多个具有相同行为但状态不同的对象,只需更改各自的状态属性。
  • 易于理解的原型链:清晰地展示了对象之间的继承关系,便于调试和理解代码结构。

📌 注意事项

  • 原型污染风险:如果原型对象被误修改,所有通过该原型创建的对象都会受到影响。
  • 非构造函数继承:不同于使用new操作符和构造函数,Object.create()不执行构造函数体内的代码,仅复制原型链。

Object.create() 是理解JavaScript原型继承机制的一个重要工具,它在需要灵活控制对象原型时尤为有用,是构建复杂对象关系的理想选择。


五、类(ES6)🏫

随着ECMAScript 2015(简称ES6)的到来,JavaScript正式引入了“类”(class)这一概念,为开发者提供了一种更接近传统面向对象语言的语法来定义和创建对象。尽管本质上仍然是基于原型的继承,但“类”为JavaScript带来了更加清晰、简洁的语法糖,使得面向对象编程变得更加直观。

📌 基本结构

class Person {
  constructor(name) {
    this.name = name; // 初始化属性
  }
  
  greet() {
    console.log(`Hello, I'm ${this.name}.`); // 定义方法
  }
}

const jane = new Person('Jane'); // 创建实例
jane.greet(); // 输出:Hello, I'm Jane.

📌 关键特性

  • constructor方法:这是类的构造函数,用于初始化新创建的对象。当使用new关键字创建类的实例时自动调用。

  • 方法定义:直接在类体内定义的方法,不需要使用function关键字,也无需像对象字面量那样将方法挂载到this上。

  • 继承:ES6的类还引入了extends关键字,用于实现继承,简化了原型链的继承过程。

class Student extends Person {
  constructor(name, grade) {
    super(name); // 调用父类构造函数
    this.grade = grade;
  }
  
  study() {
    console.log(`${this.name} is studying in grade ${this.grade}.`);
  }
}

const tom = new Student('Tom', 10);
tom.greet(); // 继承自Person类
tom.study();

📌 重要概念

  • super关键字:在子类中用于调用父类的构造函数或方法,是继承机制中的关键部分。

  • 静态方法:使用static关键字定义,属于类本身而不是实例,通过类名直接调用。

class Greeting {
  static hello() {
    console.log('Hello from the class!');
  }
}

Greeting.hello(); // 静态方法调用

ES6的类为JavaScript带来了一种更符合传统面向对象编程习惯的语法,提高了代码的可读性和可维护性。虽然其背后仍然是基于原型的继承机制,但“类”提供了一层更抽象、更易理解的接口,使得对象创建和继承的逻辑更加清晰。无论是对于初学者还是经验丰富的开发者,掌握ES6类都是提升JavaScript编程效率和代码质量的重要一步。


六、工厂模式 🏭

工厂模式是软件工程中一种常用的设计模式,它在JavaScript中用于创建对象时,通过函数(工厂函数)封装对象实例化的过程,从而隐藏了具体的创建逻辑,提高了代码的灵活性和可维护性。这种方法特别适合于需要创建多个相似对象的情况,同时又想减少重复代码。

📌 基本实现

function createPerson(name) {
  // 工厂函数:接收参数并返回一个包含该属性的对象
  return {
    name: name, // 动态设置对象的属性
    greet: function() {
      console.log(`Hi, I'm ${this.name}`); // 定义对象的方法
    }
  };
}

const mike = createPerson('Mike'); // 使用工厂函数创建对象
mike.greet(); // 输出:Hi, I'm Mike

📌 优势

  1. 封装性:工厂函数封装了对象创建的细节,使得调用者不需要关心对象是如何创建的,只需要知道如何使用它。

  2. 灵活性:容易扩展以创建不同类型的对象。只需修改或增加工厂函数即可创建具有不同属性或方法的对象,而无需改变客户端代码。

  3. 代码复用:对于具有相同属性或方法的对象,可以通过工厂函数复用这些通用部分,减少代码重复。

📌 应用场景

  • 当你需要创建多个相似但不完全相同的对象时,比如创建多个不同用户对象,每个用户有不同的名字和角色,但都有共同的属性(如greet方法)和一些不同的属性。

📌 注意事项

  • 对象识别问题:由于所有对象都是通过同一个工厂函数创建,它们没有一个显式的构造函数或类型标识,因此难以识别对象的具体类型。

  • 原型链未利用:工厂模式直接创建并返回对象字面量,没有利用JavaScript的原型链机制,可能导致内存占用稍大,尤其是在创建大量对象时。

工厂模式是JavaScript中实现对象创建的一种经典策略,通过它可以在不暴露内部创建逻辑的同时,提供一致的接口来生产对象,是实现解耦和代码复用的有效手段。


七、构造函数模式 🔨

构造函数模式是JavaScript中实现面向对象编程的一种基本方法,它利用自定义构造函数和new操作符来创建特定类型的对象实例。每个通过构造函数创建的对象都会拥有独立的属性副本和方法,适合于创建多个同类型但相互独立的对象。

📌 基本用法

function Person(name) {
  // 构造函数:初始化新对象的属性
  this.name = name;

  // 为每个实例定义方法
  this.greet = function() {
    console.log(`Hello, I'm ${this.name}.`);
  };
}

const anna = new Person('Anna'); // 使用new关键字创建实例
anna.greet(); // 输出:Hello, I'm Anna.

📌 核心特点

  1. 构造函数:以大写字母开头命名的函数,用于初始化新创建的对象的属性。

  2. this关键字:在构造函数内部,this指向新创建的对象实例。

  3. 独立性:每个实例都有自己的属性和方法副本,互不影响。

  4. new操作符:创建实例时必须使用,它负责创建空对象、绑定this并返回新对象。

📌 优缺点

  • 优点

    • 易于理解和使用,符合传统的面向对象编程习惯。
    • 可以为每个实例分配独立的属性,适合处理大量相似对象。
  • 缺点

    • 每个实例上的方法都是独立的,导致内存开销大,尤其是方法较多时。
    • 不利于函数复用,因为方法定义在构造函数内部。

📌 解决方法重定义问题

为了解决方法重复定义导致的内存浪费,可以利用原型链(prototype)来共享方法:

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

Person.prototype.greet = function() {
  console.log(`Hello, I'm ${this.name}.`);
};

const bob = new Person('Bob');
bob.greet(); // 输出:Hello, I'm Bob.

通过将方法定义在构造函数的prototype属性上,所有实例可以共享这些方法,从而节省内存。

构造函数模式JavaScript面向对象编程的基石之一,它允许开发者以更面向对象的方式组织代码,通过构造函数和原型链的结合,可以灵活地创建和管理对象。


八、原型模式 🧬

原型模式JavaScript中实现继承和方法复用的核心机制,通过利用对象的原型链,可以让所有实例共享同一组属性和方法,有效减少内存消耗,提高程序效率。每个JavaScript函数都有一个内置的prototype属性,这个属性是一个对象,用于存放所有实例共享的属性和方法。

📌 基础概念

function Person() {} // 构造函数

// 设置原型上的属性和方法
Person.prototype.name = 'Prototype User';
Person.prototype.greet = function() {
  console.log(`Greetings, I'm ${this.name}.`);
};

const emily = new Person(); // 创建实例
emily.greet(); // 输出:Greetings, I'm Prototype User.

📌 核心原理

  • 原型链:每当创建一个新对象,该对象会自动链接到其构造函数的prototype对象,形成一条原型链。这使得对象可以访问其原型上的属性和方法。

  • 共享方法:在原型上定义的方法对所有实例来说只有一份副本,节省内存。

  • 修改原型:原型上的属性和方法可以在构造函数定义之后被添加或修改,影响所有已存在的实例。

📌 优点

  1. 内存效率:方法在内存中只存在一份,所有实例共享,大大减少了内存使用。
  2. 动态扩展:可以在运行时向原型添加方法,立即对所有实例生效。
  3. 易于理解的继承:通过原型链实现简单的继承结构,易于管理和扩展。

📌 缺点

  • 原型污染:修改原型会影响所有实例,可能导致意外的行为变化。
  • 访问冲突:直接修改原型上的共有属性会影响所有实例,除非使用实例自身属性来覆写。
  • 查找性能:访问原型链上的属性可能会有轻微的性能开销,尤其是在链较长时。

📌 使用建议

  • 区分公私:尽量将不变的或共享的方法放在原型上,而实例特有的属性直接在构造函数内初始化。
  • 谨慎修改原型:考虑原型修改对已有实例的影响,尽量在设计初期完成原型的定义。

原型模式JavaScript面向对象编程的重要组成部分,通过巧妙利用原型链,可以构建高效、灵活的对象系统,理解并掌握这一模式是每位JavaScript开发者进阶的必经之路。


九、组合模式 🌈

组合模式JavaScript中体现为灵活结合多种对象创建技术,以优化代码结构、提高性能和可维护性。这种模式鼓励开发者根据具体需求,创造性地融合构造函数、原型、闭包、类等机制,实现复杂功能的同时保持代码的清晰和高效。

下面通过一个结合构造函数模式与原型模式的例子,展示如何在保证私有变量安全的同时,共享方法以减少内存消耗。

📌 示例解析

function Person(name) {
  // 使用闭包创建私有变量
  let _name = name; // 下划线前缀提示这是一个“私有”变量

  // 公共方法访问私有变量,通过闭包捕获
  this.getName = function() {
    return _name;
  };
}

// 利用原型链共享方法,减少内存占用
Person.prototype.greet = function() {
  console.log(`Hello, I'm ${this.getName()}.`);
};

const sam = new Person('Sam');
sam.greet(); // 输出:Hello, I'm Sam.

📌 组合模式的优势

  1. 灵活性:根据不同场景,自由搭配最适合的创建方式,既可保证代码的可读性,又能满足性能需求。

  2. 优化内存使用:通过原型链共享方法,避免了每个实例重复创建相同方法,节省内存资源。

  3. 封装性增强:结合闭包等技术,可以有效隐藏内部实现细节,保护数据安全,实现更高级别的封装。

📌 应用场景

  • 当你需要创建一组具有相似功能的对象,但又希望它们各自拥有独立状态或私有数据时。
  • 在构建大型应用框架或库时,为了平衡性能与易用性,经常采用组合模式来设计对象系统。

组合模式展示了JavaScript在对象设计上的灵活性,鼓励开发者根据实际情况,创造性地结合不同的设计模式和技术,以达到既满足功能需求,又优化性能和可维护性的目的。通过熟练运用组合模式,可以使你的JavaScript代码更加健壮、高效,适应各种复杂的项目需求。


十、总结 🎯

在这次深入探索之旅中,我们遍历了JavaScript对象创建的八种核心路径,每一步都揭示了这门语言在灵活性与表现力上的独到之处。从基础的Object构造函数到直观的对象字面量,再到进阶的Object.create()ES6类,以及设计模式中的工厂模式、构造函数模式、原型模式,直至灵活多变的组合模式,每一种方法都在不同的场景下绽放着光彩。

  • 对象字面量 以其简洁明了赢得了日常开发的青睐。
  • 构造函数与原型模式 结合,展现了面向对象编程的精髓。
  • ES6类 简化了继承结构,让面向对象设计更加贴近传统风格。
  • 工厂模式 强调了封装与灵活性。
  • Object.create() 直击原型链核心,强化了继承的概念。
  • 组合模式 则教会了我们如何综合运用多种技巧,达到最优的代码结构和性能平衡。

掌握这些方法,不仅仅是技术的堆砌,更是理解JavaScript内在机制、面向对象设计思想以及代码组织艺术的深刻体现。在实战中,根据项目需求灵活选择最适合的创建方式,是每一位开发者追求的境界。记住,每一块代码都是一次创造的机会,每一次实践都是通往卓越的桥梁。


🔗 相关知识

  • JavaScript 中的 Class 类
  • JavaScript中call、apply与bind的区别
  • JavaScript 垃圾回收机制深度解析:内存管理的艺术
  • 深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
  • 深入理解JavaScript事件循环Event Loop:宏任务与微任务的奇幻之旅
  • JavaScript 防抖与节流——以游戏智慧解锁实战奥秘
  • JavaScript基础知识强化:变量提升、作用域逻辑及TDZ的全面解析

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/632147.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2.2、Gitea忘记密码重置密码

忘记密码后,管理员可以使用gitea的主程序输入命令重置密码。 gitea admin user change-password --username myname --password asecurepassword

工业派-配置Intel神经计算棒二代(NCS2)

最近两天在工业派ubuntu16.04上配置了Intel神经计算棒二代——Intel Neural Compute Stick,配置过程之艰辛我都不想说了,实在是太折磨人。不过历尽千辛万苦,总算让计算棒可以在工业派ubuntu16.04系统上跑了,还是蛮欣慰的。 注&…

数据分析案例-印度美食数据可视化分析

🤵‍♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞&#x1f4…

alphassl泛域名证书13个月600

AlphaSSL是GlobalSign旗下的数字证书品牌,它主要视为客户提供两种入门级的SSL证书——DV单域名以及泛域名SSL证书。这两种SSL证书一种可以保护www和两个域名记录,或者单个子域名激励;另一种可以同时保护多个域名记录,满足了大部分…

Django视图Views

Views视图 HttpRequest 和HttpResponse Django中的视图主要用来接受web请求,并做出响应。视图的本质就是一个Python中的函数视图的响应分为两大类 1)以Json数据形式返回(JsonResponse) 2)以网页的形式返回 2.1)重定向到另一个网页 (HttpRe…

计算机组成原理(超详解!!) 第九节 外围设备

1.外围设备概述 1.外围设备的一般功能 外围设备的定义:这个术语涉及到相当广泛的计算机部件。除了CPU和主存外,计算 机系统的每一部分都可作为一个外围设备来看待。 外围设备的功能:在计算机和其他机器之间,以及计算机与用户之…

C#知识|(实例)大乐透双色球随机选号器项目实现(一)

哈喽,你好啊,我是雷工! 本节学习练习大乐透双色球随机选号器项目的实现,以下为学习笔记。 01 功能需求 当点击【启动】按钮时,号码开始随机变化; 当点击【选择】按钮时,号码停止随机变化,并将选定的号码显示到下方列表; 当点击【清除】按钮时,下方显示列表被清空。…

C# 结合 JavaScript 对 Web 控件进行数据输入验证

目录 关于数据验证 范例运行环境 验证设计 JavaScript 方法 设计 实现 调用示例 C# 方法 设计 实现 调用示例 小结 关于数据验证 在 Web 应用的录入界面,数据验证是一项重要的实现功能,数据验证是指确认 Web 控件输入或选择的数据&#xff…

Microsoft Remote Desktop Beta v10.9.7 Mac微软远程连接工具

Microsoft Remote Desktop Beta 是一种软件应用程序,使用户能够从其设备远程访问基于 Windows 的计算机或虚拟机。它可以在 Windows 和 Mac 操作系统上下载。通过 Microsoft Remote Desktop,用户可以使用远程桌面协议 (RDP) 或 RemoteFX 协议连接到远程桌…

【qt】日历和定时器

日历和定时器 一.Calendar Widget(日历组件)1.日历的基本使用 二.定时器1.定时器的用处2.创建一个定时器3.设置定时器时间间隔4.设置定时器类型5.超时信号6.关联定时器7.启动定时器8.关闭定时器9.定时器要执行功能 三.总结一下: 一.Calendar Widget(日历组件) 1.日…

亚马逊调整退货处理费,卖家如何应对新挑战?

在电子商务领域,退货处理一直是一个重要且复杂的问题。作为全球最大的电子商务平台之一,亚马逊一直在寻求优化退货处理流程,以平衡消费者满意度和运营成本。近日,亚马逊宣布自2024年6月1日起,将对退货处理费收取标准进…

ATFNet:长时间序列预测的自适应时频集成网络

ATFNet是一个深度学习模型,它结合了时间域和频域模块来捕获时间序列数据中的依赖关系。引入了一种新的加权机制来调整周期性的权重,增强了离散傅立叶变换,并包括一个复杂关系识别的注意力机制,在长期时间序列预测中优于当前方法(每…

一休:一款专业的休息提醒软件

对于长期使用电子产品的人来说,保护眼睛至关重要,不论是工作还是学习,适当的休息都是必要的,保护视力要牢记20-20-20法则,眼科医生陶勇也科普过: 使用电脑工作和学习时,容易会忘记时间&#x…

Maven 依赖排查

先从项目去看显而易见,假如我们有一个项目,父工程中包含一些子工程,如下: 我们想看一下samples-account中的依赖关系,那么我们可以打开 samples-account的pom文件,查看其maven依赖关系图。 我们可以看到此项…

WPS如何把多个表格合并到一个表格里面?

注意:此功能需要wps会员。 例如:这里有3个表格。 现在希望合并3个表格到一起,如下图所示。 新建一个表格,打开表格。 选择 开始->工作表->合并表格->整合成为一个工作薄。 弹出对话框,选择添加文件&#xff…

JETBRAINS IDES 分享一个2099通用试用码,支持一键升级!DataGrip 2024 版

文章目录 废话不多说上教程:(动画教程 图文教程)一、动画教程激活 与 升级(至最新版本) 二、图文教程 (推荐)Stage 1.下载安装 toolbox-app(全家桶管理工具)Stage 2 : 下…

AndroidStudio集成高德地图后出现黑屏并报错

报错内容为:No implementation found for void com.autonavi.base.ae.gmap.GLMapEngine.nativeMainThreadTrigger(int, long) (tried Java_com_autonavi_base_ae_gmap_GLMapEngine_nativeMainThreadTrigger and Java_com_autonavi_base_ae_gmap_GLMapEngine_nativeM…

最佳解决Maven同一依赖多版本共存问题,重复依赖(同一个jar包,多个版本)-maven-shade-plugin

先看链接:原文链接 参照原文链接生成的文件(下面是我放的位置) mvn指令 mvn install:install-file -DfileD:\mavenrepository/maven-shade.jar -DgroupIdcom.wj -DartifactIdmaven-shade -Dversion1.1 -Dpackagingjar如果配置了maven_home 和java_home可以任意打开cmd执行(…

Linux-软件安装--tomcat的安装

tomcat的安装 1、下载tomcat安装包2.移动到自己想要解压的目录3、解压文件夹4、启动tomcat5、查看tomcat进程6、查看日志7、通过浏览器访问成功8、停止tomecat服务8.1运行tomcat的bin目录中提供的停止服务的脚本文件shutdcwn.sh8.2结束tomcat进程1、下载tomcat安装包 本篇文章…

Vue原理学习:vdom 和 diff算法(基于snabbdom)

vdom 和 diff 背景 基于组件化,数据驱动视图。只需关心数据,无需关系 DOM ,好事儿。 但是,JS 运行非常快,DOM 操作却非常慢,如何让“数据驱动视图”能快速响应? 引入 vdom 用 vnode 表示真实…