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

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...

LLMs 系列实操科普(1)

写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...

在 Spring Boot 项目里,MYSQL中json类型字段使用

前言&#xff1a; 因为程序特殊需求导致&#xff0c;需要mysql数据库存储json类型数据&#xff0c;因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...