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

JavaScript------面向对象

目录

一、面向对象编程(OOP) 基本概念

二、类

1、语法

2、通过类创建对象

3、类的属性

4、类的方法

5、构造函数

三、面向对象的三个特点

1、封装

如何确保数据的安全(实现封装的方式):

2、继承

在子类中,可以通过创建同名方法来重写父类的方法。

在子类中,可以重写构造函数。

OCP 开闭原则

3、多态

四、对象的内存结构

1、对象自身

2、原型对象(prototype)

五、原型对象

1、访问一个对象的原型对象

2、原型对象中的数据

3、原型链

4、原型的作用

作用:

对比函数的原型链和Object的原型链

5、修改原型

6、检查对象自身或原型上是否有某属性的方法

6.1、instanceof

6.2、in运算符

6.3、hasOwnProperty(不推荐)

6.4、hasOwn

六、旧类

七、new运算符

八、总结


一、面向对象编程(OOP) 基本概念

1. 程序是干嘛的?  - 程序就是对现实世界的抽象(照片就是对人的抽象)

2. 对象是干嘛的?- 一个事物抽象到程序中后就变成了对象。 在程序的世界中,一切皆对象

3. 面向对象的编程 - 面向对象的编程指,程序中的所有操作都是通过对象来完成。做任何事情之前都需要先找到它的对象,然后通过对象来完成各种操作。

  • 一个事物通常由两部分组成:数据和功能
  • 一个对象由两部分组成:属性和方法
  • 事物的数据到了对象中,体现为属性
  • 事物的功能到了对象中,体现为方法

二、类

使用Object创建对象的问题: 1. 无法区分出不同类型的对象; 2. 不方便批量创建对象

在JS中可以通过类(class)来解决这个问题:类是对象模板,可以将对象中的属性和方法直接定义在类中。定义后,就可以直接通过类来创建对象。

可以说,创建对象的第一步,就是为这个对象定义一个类。

1、语法

方式一:
class 类名 {} // 类名要使用大驼峰命名方式二:
const 类名 = class {}  
const Person = class {}// Person类专门用来创建人的对象
class Person{}// Dog类式专门用来创建狗的对象
class Dog{}

2、通过类创建对象

语法:new 类()

const p1 = new Person()  // 调用构造函数创建对象
console.log(p1)   // Person{}Person()相当于把类当做一个函数在调用,加上new就是构造函数

通过同一个类创建的对象,我们称为同类对象。可以使用instanceof来检查一个对象是否是由某个类创建。

const p1 = new Person()  // 调用构造函数创建对象
const p2 = new Person()const d1 = new Dog()
const d2 = new Dog()console.log(p1 instanceof Person) // true
console.log(d1 instanceof Person) // false

如果某个对象是由某个类所创建,则我们称该对象是这个类的实例。以上代码中p1、p2是Person类的实例,d1、d2是Dog类的实例。

3、类的属性

类是创建对象的模板,要创建第一件事就是定义类。

类的代码块,默认就是严格模式,类的代码块是用来设置对象的属性的,不是什么代码都能写的。

  1. 实例属性只能由实例对象访问的
  2. static声明的属性,只能通过类访问,实例对象是无法访问的
class Person{name = "孙悟空" // Person的实例属性name, p1.name、p2.nameage = 18       // 实例属性只能通过实例访问, p1.age、p2.agestatic test = "test静态属性" // 使用static声明的属性,是静态属性(类属性) Person.teststatic hh = "静态属性"   // 静态属性只能通过类去访问, Person.hh   实例对象中是没有的
}

4、类的方法

添加方法的方式有2种。

class Person{name = "孙悟空"// 添加方法的一种方式(不推荐使用,{}内有无内容,打印p1时都会显示该方法)// sayHello = function(){// } // 添加方法(实例方法),方法中也就是{}中没写内容,打印p1时不会显示sayHello,但是方法已经加入到Person中了 sayHello(){console.log('大家好,我是' + this.name)   // 实例方法中this就是当前实例p1} // 静态方法(类方法) 通过类来调用 static test(){console.log("我是静态方法", this)   // 静态方法中this指向的是当前类Person} 
}const p1 = new Person()
console.log(p1)
Person.test()
p1.sayHello()   // 哈哈哈

5、构造函数

当我们在类中直接指定实例属性的值时,意味着我们创建的所有对象的属性都是这个值。因此,希望每次new类对象时,每个实例对象的属性的值都是不一样的。

在类中可以添加一个特殊的方法constructor,该方法我们称为构造函数(构造方法),构造函数会在我们调用类创建对象时执行。

class Person{constructor(name, age, gender){console.log("构造函数执行了~")     // 构造函数会在我们调用类创建对象时执行}
}const p1 = new Person()
console.log(p1)    //  构造函数执行了~class Person{constructor(name, age, gender){// 可以在构造函数中,为实例属性进行赋值,用this// 在构造函数中,this表示当前所创建的对象this.name = name   // 将参数的name赋值给Person对象的name实例属性this.age = agethis.gender = gender}
}const p1 = new Person("孙悟空", 18, "男")   // 向Person里传的参数,实际上就是传给构造函数
const p2 = new Person("猪八戒", 28, "男")
const p3 = new Person("沙和尚", 38, "男")console.log(p1)    // {name:"孙悟空", age:18,gender:"男"}
console.log(p2)    // {}
console.log(p3)    // {}

三、面向对象的三个特点

面向对象的特点:封装(安全性)、继承(扩展性)和多态(灵活性)

1、封装

装:对象就是一个用来存储不同属性的容器。

封:对象不仅存储属性,还要负责数据的安全,保证数据的合法性(比如年龄不能为负数)。直接添加到对象中的属性,并不安全,因为它们可以被任意的修改。

如何确保数据的安全(实现封装的方式):

1.私有化数据

将需要保护的数据设置为私有,只能在类内部使用

class Person {#address = "花果山" // 实例使用#开头就变成了私有属性,私有属性只能在类内部访问sayHello() {console.log(this.#address)}
}const p1 = new Person()console.log(p1.#address)  // 报错,私有属性不能访问
console.log(p1.sayHello())  // 花果山

私有化属性一定要先声明再使用,否则会报错

class Person {#name#age#genderconstructor(name, age, gender) {this.#name = namethis.#age = agethis.#gender = gender}const p1 = new Person("孙悟空", 18, "男")
console.log(p1)  // Person{#name: "孙悟空",#age: 18,#gender: "男"}p1.#age = 11  // 报错,私有属性无法访问,更无法更改

2.提供setter和getter方法来开放对数据的操作

属性设置私有,通过getter setter方法操作属性带来的好处:

  • ①可以控制属性的读写权限:数据只读,就只有getter方法;数据只写,只有setter方法;数据可读写,有getter和getter方法;数据不可读也不可写,getter和getter方法都无;
  • ②可以在方法中对属性的值进行验证:在方法中添加一些数据的条件,如年龄不能为负数
class Person {#name#age#genderconstructor(name, age, gender) {this.#name = namethis.#age = agethis.#gender = gender}// getter方法,用来读取属性getName(){return this.#name}// setter方法,用来设置属性setName(name){this.#name = name}getAge(){return this.#age}setAge(age){if(age >= 0){this.#age = age}}}const p1 = new Person("孙悟空", 18, "男")p1.getName()
p1.setName('猪八戒')console.log(p1)  // Person{#name: "猪八戒",#age: 18,#gender: "男"}

为了访问属性时不用像上面的getter方法一样麻烦,可以这么写访问函数:

class Person {#genderconstructor(gender) {this.#gender = gender}get gender(){return this.#gender}set gender(gender){this.#gender = gender}
}const p1 = new Person("孙悟空", 18, "男")// 读取属性的值,调用get方法
console.log(p1.gender)  // 男    // 修改属性的值,调用set方法
p1.gender = "女" 
console.log(p1.gender)  // 女

2、继承

通过extends关键来完成继承。当一个类继承另一个类时,就相当于将另一个类中的代码复制到了当前类中(简单理解)。继承发生时,被继承的类称为 父类(超类),继承的类称为 子类。通过继承可以减少重复的代码,并且可以在不修改一个类的前提对其进行扩展。

class Animal{constructor(name){this.name = name}sayHello(){console.log("动物在叫~")}
}class Dog extends Animal{}class Cat extends Animal{}const dog = new Dog("旺财")
const cat = new Cat("汤姆")dog.sayHello()  // 动物在叫~
cat.sayHello()  // 动物在叫~

不用继承,以上代码就会重复冗余,写成如下形式:

class Dog extends Animal{constructor(name){this.name = name}sayHello(){console.log("动物在叫~")}
}class Cat extends Animal{constructor(name){this.name = name}sayHello(){console.log("动物在叫~")}
}const dog = new Dog("旺财")
const cat = new Cat("汤姆")dog.sayHello()  // 动物在叫~
cat.sayHello()  // 动物在叫~

在子类中,可以通过创建同名方法来重写父类的方法。

class Animal{constructor(name){this.name = name}sayHello(){console.log("动物在叫~")}
}class Dog extends Animal{sayHello(){console.log("汪汪汪")}
}class Cat extends Animal{sayHello(){console.log("喵喵喵")}            
}const dog = new Dog("旺财")
const cat = new Cat("汤姆")dog.sayHello()  // 汪汪汪
cat.sayHello()  // 喵喵喵

在子类中,可以重写构造函数。

重写构造函数时,构造函数的第一行代码必须为super(),表示继承父类的构造函数。

class Animal{constructor(name){this.name = name}sayHello(){console.log("动物在叫~")}
}class Cat extends Animal{// 重写构造函数constructor(name, age){   // 一定要写传入的参数,否则属性值为undefined// 重写构造函数时,构造函数的第一行代码必须为super()super(name) // 调用父类的构造函数,继承了父类的name属性,所以一定要写name参数//如果不写,那就自己重写name属性=》this.name = namethis.age = age}sayHello(){super.sayHello()  // 在方法中使用super来继承父类的方法console.log("喵喵喵")}            
}const cat = new Cat("汤姆", 3)console.log(cat)   // Cat{name:"汤姆", age: 3}cat.sayHello()  // 动物在叫~     喵喵喵

OCP 开闭原则

程序应该对修改关闭,对扩展开放。尽量不修改父类,而是用一个子类继承父类,父类的方法、属性中子类需要的就保留,不需要的就不要,然后在子类再扩展一些子类需要的属性、方法。

3、多态

在JS中不会检查参数的类型,所以这就意味着任何数据都可以作为参数传递。要调用某个函数,无需指定的类型,只要对象满足某些条件即可。多态为我们提供了灵活性

class Person{constructor(name){this.name = name}
}class Dog{constructor(name){this.name = name}
}const dog = new Dog('旺财')
const person = new Person("孙悟空")function sayHello(obj){console.log("Hello,"+obj.name)
}sayHello(dog)   // Hello, 旺财
sayHello(person)   // Hello, 孙悟空

四、对象的内存结构

对象中存储属性的区域实际有两个:对象自身和原型对象

1、对象自身

直接通过对象所添加的属性,位于对象自身中。

在类中通过 属性名 = 属性值 的形式添加的属性,位于对象自身中。

2、原型对象(prototype)

对象中还有一些内容,会存储到其他的对象里(原型对象)。

在对象中会有一个属性用来存储原型对象,这个属性叫做__proto__

原型对象也负责为对象存储属性,当我们访问对象中的属性时,会优先访问对象自身的属性,对象自身不包含该属性时,才会去原型对象中寻找。

 会添加到原型对象中的情况:

  • 在类中通过xxx(){}方式添加的方法,位于原型中
  • 主动向原型中添加的属性或方法
class Person {name = "孙悟空"age = 18constructor(){this.gender = "男"}sayHello() {console.log("Hello,我是", this.name)}
}const p = new Person()console.log(p.sayHello)   // Hello,我是孙悟空p.sayHello = "hello"
console.log(p.sayHello)   // hello    先从自身属性找sayHello

在内存中,上述代码的表现:

五、原型对象

1、访问一个对象的原型对象

语法:对象.__proto__   or   Object.getPrototypeOf(对象)

PS:浏览器不建议使用对象.__proto__去访问对象的原型对象,所以提供了Object.getPrototypeOf(对象)去访问对象的原型对象

class Person {name = "孙悟空"age = 18sayHello() {console.log("Hello,我是", this.name)}
}const p = new Person()console.log(p)   // {name:"孙悟空", age: 18}
console.log(p.__proto__)  // {constructor:f, sayHello: f}
console.log(Object.getPrototypeOf(p))    // {constructor:f, sayHello: f}

2、原型对象中的数据

  • 1. 对象中的数据(属性、方法等)
  • 2. constructor (对象的构造函数),类里面没有就找原型的构造函数
class Person {name = "孙悟空"age = 18sayHello() {console.log("Hello,我是", this.name)}
}const p = new Person()// Person类里面没有constructor,所以去原型里找
console.log(p.__proto__.constructor)  // 打印整个class Person
console.log(p.constructor)  // 打印整个class Person

原型对象也有原型。这样就构成了一条原型链。

class Person {name = "孙悟空"age = 18sayHello() {console.log("Hello,我是", this.name)}
}const p = new Person()console.log(p.__proto__.__proto__)  // 原型对象也有原型
console.log(p.__proto__.__proto__.__proto__)  // null

根据对象的复杂程度不同,原型链的长度也不同。空对象的原型存在、原型的原型不存在。

class Person {name = "孙悟空"age = 18sayHello() {console.log("Hello,我是", this.name)}
}const p = new Person()console.log(p.__proto__.__proto__)  // 原型对象也有原型
console.log(p.__proto__.__proto__.__proto__)  // nullconst obj = {}
console.log(obj.__proto__)    // 存在
console.log(obj.__proto__.__proto__)    // null

3、原型链

读取对象属性时,会优先对象自身属性,如果对象中有,则使用,没有则去对象的原型中寻找如果原型中有,则使用,没有则去原型的原型中寻找,直到找到Object对象的原型(Object的原型没有原型(为null))。如果依然没有找到,则返回undefined。

作用域链与原型链的区别:

  • 作用域链,是找变量的链,找不到会报错
  • 原型链,是找属性的链,找不到会返回undefined

4、原型的作用

所有的同类型对象它们的原型对象都是同一个,也就意味着,同类型对象的原型链是一样的

class Person {name = "孙悟空"age = 18sayHello() {console.log("Hello,我是", this.name)}
}const p = new Person()
const p2 = new Person()console.log(p === p2)  // false
console.log(p.__proto__ === p2.__proto__)  // trueconst d = new Dog()
console.log(d === p)  // false
console.log(d.__proto__ === p.__proto__)  // false,因为d和p不同类

作用:

原型就相当于是一个公共的区域,可以被所有该类实例访问,可以将该类实例中,所有的公共属性(方法)统一存储到原型中。这样我们只需要创建一个属性,即可被所有实例访问

在对象中有些值是对象独有的,像属性(name,age,gender)每个对象都应该有自己值,但是有些值对于每个对象来说都是一样的,像各种方法,对于一样的值没必要重复的创建。

如果只有少数对象的方法与其他的不一样,那么就实例.方法 = 新方法内容进行修改即可。

JS中继承就是通过原型来实现的,当继承时,子类的原型就是一个父类的实例。

class Animal{
}class Cat extends Animal{
}class TomCat extends Cat{
}const cat = new Cat()
console.log(cat)   // Cat{}
console.log(cat.__proto__)   // Animal{}cat --> Animal实例 --> object --> Object原型 --> null
TomCat --> cat --> Animal实例 --> object --> Object原型 --> null

所有类都是object的子类

对比函数的原型链和Object的原型链

  • 函数的原型链:
    function A(){
    };
    var f1 = new A();f1.proto ==>A.prototype ==> A.prototype.proto ==> Object.prototype ==> Object.prototype.proto ==> null---------------------------------------------------------function A(){
    };A.proto ==>Function.prototype ==>Function.prototype.proto ==> Object.prototype ==> Object.prototype.proto ==> null
    
  • Object的原型链:

5、修改原型

通过类的prototype属性,修改应在类定义好之后。好处:①一修改就是修改所有实例的原型,②无需创建实例即可完成对类的修改

语法:类.prototype

通过类的实例去修改原型,原则上不太好,因为是通过一个对象影响所有同类对象,这么做不合适。

class Person {name = "孙悟空"age = 18sayHello() {console.log("Hello,我是", this.name)}
}Person.prototype.fly = () => {console.log("我在飞!")
}

最好不要直接给prototype去赋值,因为会把原来的东西覆盖掉

6、检查对象自身或原型上是否有某属性的方法

6.1、instanceof

作用:检查一个对象是否是一个类的实例。检查的是对象的原型链上是否有该类实例,只要原型链上有该类实例,就会返回true。

Object是所有对象的原型,所以任何和对象和Object进行instanceof运算都会返回true。

class Animal {}class Dog extends Animal {}const dog = new Dog()console.log(dog instanceof Dog) // true
console.log(dog instanceof Animal) // true
console.log(dog instanceof Object) // truedog(Dog的实例) -> Animal的实例 -> Object实例 -> Object原型

6.2、in运算符

使用in运算符检查属性时,无论属性在对象自身还是在原型中,都会返回true

class Person {name = "孙悟空"age = 18sayHello() {console.log("Hello,我是", this.name)}
}const p = new Person()console.log("name" in p)   // true
console.log("sayHello" in p)   // true

6.3、hasOwnProperty(不推荐)

作用:用来检查一个对象的自身是否含有某个属性,有则返回true。原型上的属性返回false。

语法:对象.hasOwnProperty(属性名)

class Person {name = "孙悟空"age = 18sayHello() {console.log("Hello,我是", this.name)}
}const p = new Person()console.log(p.hasOwnProperty("name"))   // true
console.log(p.hasOwnProperty("sayHello"))   // false
console.log(p.__proto__.__proto__.hasOwnProperty("hasOwnProperty"))  // true

6.4、hasOwn

作用:新增的静态方法,用来检查一个对象的自身是否含有某个属性。

语法:Object.hasOwn(对象, 属性名)

class Person {name = "孙悟空"age = 18sayHello() {console.log("Hello,我是", this.name)}
}const p = new Person()console.log(Object.hasOwn(p, "name"))   // true
console.log(Object.hasOwn(p, "sayHello"))   // false

六、旧类

早期JS中,直接通过函数来定义类。

一个函数如果直接调用 xxx() 那么这个函数就是一个普通函数。一个函数如果通过new调用 new xxx() 那么这个函数就是一个构造函数。

// 用立即执行函数将对象的所有代码包裹起来
var Person = (function() {function Person(name, age) {// 在构造函数中,this表示新建的对象this.name = namethis.age = age// this.sayHello = function(){//     console.log(this.name)// }}// 向原型中添加属性(方法)Person.prototype.sayHello = function () {console.log(this.name)}// 静态属性Person.staticProperty = "xxx"// 静态方法Person.staticMethod = function () {}return Person})()

旧类的继承:

var Animal = (function(){function Animal(){}return Animal
})()var Cat = (function(){function Cat(){}// 继承AnimalCat.prototype = new Animal()return Cat
})()var cat = new Cat()console.log(cat)

七、new运算符

官网:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new

当使用new去调用一个函数时,这个函数将会作为构造函数调用,使用new调用函数时,将会发生这些事:

  • 1. 创建一个普通的JS对象(Object对象 {}), 为了方便,称其为新对象
  • 2. 将构造函数的prototype属性设置为新对象的原型
  • 3. 使用实参来执行构造函数,并且将新对象设置为函数中的this
  • 4. 如果构造函数返回的是一个非原始值,则该值会作为new运算的返回值返回(千万不要这么做)。如果构造函数的返回值是一个原始值或者没有指定返回值,则新的对象将会作为返回值返回。通常不会为构造函数指定返回值。

八、总结

面向对象本质就是,编写代码时所有的操作都是通过对象来进行的。

面向对象的编程的步骤:

          1. 找对象

          2. 搞对象:调用属性、修改属性、调用方法、修改方法

学习对象:

          1. 明确这个对象代表什么,有什么用    

          2. 如何获取到这个对象

          3. 如何使用这个对象(对象中的属性和方法)

对象的分类:

         内建对象

                 - 由ES标准所定义的对象

                 - 比如 Object Function String Number ....

         宿主对象

                  - 由浏览器提供的对象

                  - BOM、DOM

         自定义对象

                  - 由开发人员自己创建的对象

           

相关文章:

JavaScript------面向对象

目录 一、面向对象编程(OOP) 基本概念 二、类 1、语法 2、通过类创建对象 3、类的属性 4、类的方法 5、构造函数 三、面向对象的三个特点 1、封装 如何确保数据的安全(实现封装的方式): 2、继承 在子类中&a…...

charles+夜神模拟器抓包

1.资料地址: 链接:https://pan.baidu.com/s/1w9qYfFPJcduN4If50ICccw 提取码:a7xa2.安装charles 和夜神模拟器并配置参考地址: https://www.beierblog.com/archives/%E4%BA%B2%E6%B5%8B%E5%AE%8C%E5%85%A8%E5%8F%AF%E8%A1%8Ccharles%E6%8A%93%E5%8C%85%E…...

【STC15单片机】模拟I2C操作AT24C02数据读取【更新中】

目录 I2C时序结构 I2C代码 AT24C02代码(继承I2C底层代码) PCF8591 PCB上线的长短可能影响数据传输的时间,写I2C时序可能就要加一点延时 I2C时序结构 起始条件:SCL高电平期间,SDA从高电平切换到低电平终止条件&…...

Hadoop

Hadoop Hadoop1.x 2.x 3.x区别 Hadoop1.x组成:MapReduce负责计算和资源调度,HDFS负责数据存储,Common辅助工具。 Hadoop2.x组成:MapReduce负责计算,Yarn负责资源调度,HDFS负责数据存储,Commo…...

ArrayList源码+扩容机制分析

1. ArrayList 简介 ArrayList 的底层是数组队列,相当于动态数组。与 Java 中的数组相比,它的容量能动态增长。在添加大量元素前,应用程序可以使用ensureCapacity操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。 ArrayLis…...

数据库(第四次作业)

学生表:Student (Sno, Sname, Ssex , Sage, Sdept) 学号,姓名,性别,年龄,所在系 Sno为主键 课程表:Course (Cno, Cname,) 课程号,课程名 Cno为主键 学生选课表:SC (Sno, Cno, Score)…...

传统档案管理,为什么影响企业上市进度?

企业上市,对于很多创业者来说,是他们奋发努力的首要目标。企业通过上市,进行股权融资,扩大经营规模,加速促进公司成长,最终达到企业的可持续发展。而要实现成功上市,企业除了需要满足股份公司上…...

9个EXCEL舍入函数公式的用法和实例

用法和实例 1. ROUND ROUND函数可以将数字四舍五入到指定的小数位数。 语法:ROUND(number, num_digits) number:要四舍五入的数字。 num_digits:要保留的小数位数。 举例: ROUND(3.14159,2),结果为3.14 ROUND(3.141…...

设计模式:代理模式给原始类附加功能

一、代理模式 1、定义 在不改变原始类(被代理类)的情况下,通过引入代理类来给原始类附加功能。 一般情况下,让代理类和原始类实现同样的接口。 但是,如果原始类并没有定义接口,并且原始类代码并不是我们…...

JavaScript刷LeetCode拿offer-链表篇

一、链表 链表(Linked List)是一种常见的基础数据结构,也是线性表的一种。 一个线性表是 n 个具有相同特性的数据元素的有限序列,线性表的存储结构分为两类:顺序表(数组)和链表。 链表相比较顺…...

CPP2022-28-期末模拟测试01

6-1 实现一个计算三角形面积的简单函数(假设输入的边长合理)。 分数 10 全屏浏览题目 切换布局 作者 王和兴 单位 东北大学秦皇岛分校 实现一个计算三角形面积的简单函数(假设输入的边长合理)。 函数接口定义: do…...

牛客网Python篇数据分析习题(五)

1.现有牛客网12月每天练习题目的数据集nowcoder.csv。包含如下字段(字段之间用逗号分隔): user_id:用户id question_id:问题编号 result:运行结果 date:练习日期 请你统计答对和答错的总数分别是多少。 imp…...

华为OD机试真题JAVA实现【人数最多的站点】真题+解题思路+代码(20222023)

🔥系列专栏 华为OD机试(JAVA)真题目录汇总华为OD机试(Python)真题目录汇总华为OD机试(C++)真题目录汇总华为OD机试(JavaScript)真题目录汇总文章目录 🔥系列专栏题目输入输出示例一输入输出说明解题思路核心知识点Code运行结果版权说...

ROS2机器人编程简述humble-第四章-IMPROVED DETECTOR .4

ROS2之TF2小练习-颜色随机器人和障碍物直接距离变化ROS2之TF2小练习-有哪些bug找找看里面给出了:ROS2机器人编程简述humble-第四章-BASIC DETECTOR .3需要改进哪些地方呢?检测之后,距离不变了……如何变化?这个问题可以问chatgpt吗…...

依存句法分析 -- tag和dep释义

依存句法分析(Dependency Parsing, DP)是通过分析语言单位内成分之间的依存关系揭示其句法结构,主张橘子 中核心动词是支配其它成分的中心成分,而它本身却不受其他任何成分的支配,所有受支配成分都以某种关系从属于支配…...

服务器常见的网络攻击以及防御方法

网络安全威胁类别 网络内部的威胁,网络的滥用,没有安全意识的员工,黑客,骇客。 木马攻击原理 C/S 架构,服务器端被植入目标主机,服务器端通过反弹连接和客户端连接。从而客户端对其进行控制。 病毒 一…...

Python期末复习知识点大合集(期末不挂科版)

Python期末复习知识点大合集(期末不挂科版) 文章目录Python期末复习知识点大合集(期末不挂科版)一、输入及类型转换二、格式化输出:字符串的format方法三、流程控制四、随机数生成五、字符串六、序列索(含字…...

Echarts 雷达图设置拐点大小和形状,tooltip后文字不居中对齐

第017个点击查看专栏目录Echarts的雷达图的拐点大小和形状是可以设置的,在series中设置symbol 相应的属性即可。 使用tooltip的时候,默认状态文字是居中对齐的,不好看。需要在tooltip属性中设置一下,如图所示,效果比较…...

Lesson 7.1 无监督学习算法与 K-Means 快速聚类

文章目录一、聚类算法与无监督学习二、K-Means 快速聚类的算法原理1. K-Means 快速聚类的基本执行流程2. K-Means 快速聚类的背后的数学意义三、K-Means 快速聚类的 sklearn 实现方法1. sklearn 中实现 K-Means 快速快速聚类2. 轮廓系数基本概念与 sklearn 中实现方法从现在开始…...

优维低代码:Legacy Templates 构件模板

优维低代码技术专栏,是一个全新的、技术为主的专栏,由优维技术委员会成员执笔,基于优维7年低代码技术研发及运维成果,主要介绍低代码相关的技术原理及架构逻辑,目的是给广大运维人提供一个技术交流与学习的平台。 连载…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...

【机器视觉】单目测距——运动结构恢复

ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛&#xf…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

Selenium常用函数介绍

目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...

【Linux】Linux 系统默认的目录及作用说明

博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 ​二、实现思路 总体思路: 用户通过Gradio界面上…...