当前位置: 首页 > 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年低代码技术研发及运维成果,主要介绍低代码相关的技术原理及架构逻辑,目的是给广大运维人提供一个技术交流与学习的平台。 连载…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

测试markdown--肇兴

day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"&#xff0…...

反射获取方法和属性

Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...