js构造函数和原型对象,ES6中的class,四种继承方式

一、构造函数

1.构造函数是一种特殊的函数,主要用来初始化对象
2.使用场景

常见的{...}语法允许创建一个对象。可以通过构造函数来快速创建多个类似的对象

 const Peppa = {
        name: '佩奇',
        age: 6,
        sex: '女'
    }
    const George = {
        name: '乔治',
        age: 3,
        sex: '男'
    }
    const Mum = {
        name: '佩奇妈妈',
        age: 30,
        sex: '女'
    }
    const Dad = {
        name: '佩奇爸爸',
        age: 32,
        sex: '男'
    }

    function Pig(name, age, sex) {
        this,
        name = name;
        this.age = age;
        this.sex = sex;
    }
    const Peppa1 = new Pig('佩奇', 6, '女')
    const George1 = new Pig('乔治', 3, '男')
    const Mum1 = new Pig('佩奇妈妈', 30, '女')
    const Dad1 = new Pig('佩奇爸爸', 32, '男')

构造函数在技术上是常规函数

命名以大写字母开头。

通过new关键字来执行。

3.创建构造

使用new关键字调用函数的行为被称为实例化

实例化构造函数时没有参数可以省略()

构造函数内部无需写return,返回值即为新创建的对象

构造函数内部的return返回的值无效,所以不需要写return

new Object()和new Date()也是实例化的构造函数

4.实例化执行过程!

a.创建新空对象,

b.构造函数this指向新对象,

c.执行构造函数代码,修改this,添加新的属性,

d.返回新对象

5.实例成员和静态成员

实例成员:通过构造函数创建的对象称为实例对象,实例对象中的属性和方法称为实例成员(实例属性和实例方法)

为构造函数传入参数,创建结构相同但值不同的对象

构造函数创建的实例对象彼此独立互不影响

    //实例对象上的属性和方法属于实例成员
    function Pig(name) {
        this.name = name;
    }
    const peiqi = new Pig('佩奇')
    const qiaozhi = new Pig('乔治')
    peiqi.name = '小猪佩奇' //实例属性
    peiqi.sayHi = () => { //实例方法
        console.log('hi~');
    }
    console.log('peiqi', peiqi);
    console.log('qiaozhi', qiaozhi);

构造函数的属性和方法称为静态成员(静态属性和静态成员)

静态成员只能通过构造函数来访问

静态方法中的this指向构造函数

    //构造函数上的属性和方法称为静态成员
    function Pig(name) {
        this.name = name;
    }
    Pig.eyes = 2 //静态属性
    console.log('Pig.eyes', Pig.eyes);
    Pig.sayHi = function() { //静态方法
        console.log(this);
    }
    console.log('Pig.sayHi', Pig.sayHi);

6.内置构造函数

引用类型Object,Array,RegExp,Date等

包装类型String,Number,Boolean等

Object的静态方法Object.keys(),Object.values(),Object.assign()

    const o = {
            name: '佩奇',
            age: 6
        }
    //获取所有属性名,返回数组
    console.log(Object.keys(o));

    //获取所有属性值,返回数组
    console.log(Object.values(o));

    //拷贝对象
    const oo = {}
    Object.assign(oo, o)
    //给对象添加属性
    console.log(oo);
    Object.assign(o, {
        gender: '女'
    })
    console.log(o);

二、编程思想

1.面向过程

分析解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次调用。按照分析好了的步骤,按照步骤解决问题。

优点:性能比面向对象高,适合和硬件联系很紧密的东西

缺点:没有面向对象易维护、易复用、易扩展

2.面向对象

把食物分解成一个一个对象,然后由对象之间分工与工作。

以功能来划分问题,而不是步骤。

面向对象编程(oop):在面向对象程序开发中,每一个对象都是功能中心,具有明确分工。面向对象编程具有灵活,代码可复用,容易维护和开发的优点,更适合多人合作的大型软件项目。

优点:封装性,继承性,多态性。可以使系统更加灵活,更加易于维护

缺点:性能比面向过程低

js实现面向对象需要借助构造函数来实现

构造函数实例创建的对象彼此独立,互不影响。

构造函数存在浪费性能的问题
    function Star(name, age, sex) {
        this.name = name;
        this.age = age;
        this.sing = function() {
            console.log('sing');
        };
    }
    const ldh = new Star('ldh', 55)
    const zxy = new Star('zxy', 58)
    console.log(ldh.sing === zxy.sing); //false

三、原型

原型可以解决构造函数里浪费内存的问题。

1.目的:能够利用原型对象实现方法共享

构造函数通过原型分配的函数是所有对象所共享的。

js规定:每一个构造函数都有一个prototype属性,指向另一个对象,我们也称为原型对象。

这个对象可以挂载函数,对象实例化不会多次创建原型上函数,节约内存。

我们可以把那些不变的方法,直接定义在prototype对象上,这样所有对象的实例就可以共享这些方法。

    function Star(name, age, sex) {
      //公共属性写到构造函数里
        this.name = name;
        this.age = age;
    }
    const ldh = new Star('ldh', 55)
    const zxy = new Star('zxy', 58)
    console.log('Star.prototype', Star.prototype)
    //构造函数有一个prototype属性,公共方法写到原型对象身上
    Star.prototype.sing = function() {
        console.log('唱歌');
    };
    ldh.sing()
    zxy.sing()
    console.log(ldh.sing === zxy.sing); //true

构造函数和原型对象中的this都指向实例化对象。

    let a;
    let b;

    function Star(name, age, sex) {
        a = this;
        this.name = name;
        this.age = age;
    }
    const ldh = new Star('ldh', 55)
    console.log(a === ldh);//true

    //构造函数里面的 this就是实例对象
    Star.prototype.sing = function() {
        b = this;
        console.log('唱歌');
    };
    ldh.sing()
    console.log(b === ldh);//true
    //自己定义数组扩展方法max,min,sum
    Array.prototype.max = function() {
        //原型函数里面的this指向实例化对象arr
        return Math.max(...this)
    }
    Array.prototype.min = function() {
        //原型函数里面的this指向实例化对象arr
        return Math.min(...this)
    }
    Array.prototype.sum = function() {
        //原型函数里面的this指向实例化对象arr
        return this.reduce((sum, item) => sum + item, 0)
    }
    const arr = [1, 2, 3]
    console.log(arr.max());
    console.log(arr.min());
    console.log(arr.sum());
2.constructor属性

每个原型对象里面都有一个constructor属性,该属性指向该原型对象的构造函数.

    function Star() {}
    const ldh = new Star()
    console.log(Star.prototype.constructor === Star);//true

 如果有多个对象的方法,我们可以给原型对象采取对象形式赋值。

但是这样就会覆盖构造函数原型对象原来的内容,修改后原型对象constructor就不再指向当前构造函数了,我们需要在修改后的原型对象中,添加一个constructor指向原来的构造函数。

    function Star() {}
    // Star.prototype.sing = function() {
    //     console.log('唱歌');
    // }
    // Star.prototype.dance = function() {
    //         console.log('跳');
    //     }
    Star.prototype = {
        //重新指回创造这个原型对象的构造函数
        constructor: Star,
        sing: function() {
            console.log('唱歌');
        },
        dance: function() {
            console.log('跳');
        }
    }
    console.log(Star.prototype);

 

3.原型

在每个对象都会有一个__proto_指向构造函数的prototype原型对象,之所以我们可以使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto_原型存在。

__protp_是js非标准属性,[prototype]和__protp_意义相同

用来表明当前实例对象指向哪个原型对象prototype

__protp_对象原型里面也有一个constructor属性,指向创建该实例对象的构造函数。

    function Star() {}
    const ldh = new Star()
    //每一个构造函数都有一个prototype属性,指向另一个对象,我们也称为原型对象。
    console.log('Star.prototype', Star.prototype);
    //每个原型对象里面都有一个constructor属性,该属性指向该原型对象的构造函数.
    console.log(Star.prototype.constructor === Star);//true
    //ldh.__proto__ 指向该构造函数的原型对象
    console.log(ldh.__proto__ === Star.prototype); //true
    //对象原型里面也有constructor属性,指向创建该实例对象的构造函数。
    console.log(ldh.__proto__.constructor === Star); //true

总结

prototype是原型对象,构造函数都自动有原型对象

construvtor属性在原型对象(prototype)和对象原型(__proto__)上都有 ,指向创建实例对象/原型的构造函数。

__proto__属性在实例对象里面,指向原型对象。

4.原型继承

继承是面向对象编程的另一个特征,通过继承进一步提升代码封装的程度,js中大多是借助原型对象实现继承的特性。

    const Person = {
        head: 1,
        eyes: 2
    }
    function Woman() {}
    //Woman通过原型来继承Person
    Woman.prototype = Person
    //指回原来的构造函数
    Woman.prototype.constructor = Woman
    const red = new Woman()
    console.log('red', red);

问题:同时使用了同一个对象,根据引用类型的特点,他们指向同一个对象,修改一个都会改变。


    const Person = {
        head: 1,
        eyes: 2
    }

    function Woman() {}
    Woman.prototype = Person
    Woman.prototype.constructor = Woman
    Woman.prototype.sing = function() {
        console.log('唱歌');
    }
    const red = new Woman()
    console.log('red', red);


    function Man() {}
    Man.prototype = Person
    Man.prototype.constructor = Man
    const bob = new Man()
    console.log('bob', bob);

    function Person() {
        this.head = 1
        this.eyes = 2
    }

    function Woman() {}
    //父构造函数(父类)子构造函数(子类) 子类的原型=new父类
    Woman.prototype = new Person()
    Woman.prototype.constructor = Woman
    Woman.prototype.sing = function() {
        console.log('唱歌');
    }
    const red = new Woman()
    console.log('red', red);

    function Man() {}
    Man.prototype = new Person()
    Man.prototype.constructor = Man
    const bob = new Man()
    console.log('bob', bob);

5.原型链

基于原型对象的继承使得不同的构造函数的原型对象关联在一起,并且这种关联的关系是一种链状结构,我们将原型对象的链状结构关系称为原型链。

    function Person() {}
    const ldh = new Person()
    console.log(ldh.__proto__);
    console.log(Person.prototype);
    console.log(ldh.__proto__ === Person.prototype); //true
    console.log(Person.prototype.__proto__ === Object.prototype); //true
    console.log(Object.prototype.__proto__); //null
    console.log(ldh instanceof Person); //true
    console.log(ldh instanceof Object); //true

原型链查找规则

a.当访问一个对象的属性时,首先查找这个对象自身有没有该属性。

b.如果没有就查找它的原型,也就是__proto__指向的prototype原型对象。

c.如果没有找到就查找原型对象的原型。

d.依次类推一直找到Object为之。

e.__proto__对象原型的意义就在于为对象成员查找机制提供一个方向。

f.可以使用instanceof运算符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上

四、示例

1.封装模态框 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <button id="delete">删除</button>
    <button id="login">登录</button>
</body>
</html>

<script>
    //构造函数封装模态框
    function Modal(title = '', message = '') {
        // 1.创建div标签
        // 2.给div标签添加类名modal
        // 3.modal盒子内部填充2个div并且修改文字内容
        this.modalBox = document.createElement('div')
        this.modalBox.className = "modal"
        this.modalBox.innerHTML = `<div class="header">${title}<i>x</i></div>
    <div class="main">${message}</div>`
    }

    //挂载open方法
    Modal.prototype.open = function() {
        //准备open显示时先判断 页面中有没有modal,有就移除,没有就添加
        const box = document.querySelector('.modal')
        box && box.remove()
        document.body.append(this.modalBox)
            //等盒子显示出来,就可以绑定关闭事件
        this.modalBox.querySelector('i').addEventListener('click', () => {
            //需要用箭头函数,这个this指向实例对象
            this.close()
        })
    }
    Modal.prototype.close = function() {
        this.modalBox.remove()
    }

    document.querySelector('#delete').addEventListener('click', () => {
        const del = new Modal('温馨提示', '你没有权限删除')
        del.open()
    })
    document.querySelector('#login').addEventListener('click', () => {
        const login = new Modal('友情提示', '你没有注册')
        login.open()
    })
</script>
 2.选项卡(构造函数写法)

 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #box div,
        #box1 div {
            width: 200px;
            height: 50px;
            background-color: palegreen;
            display: none;
        }
        
        .active {
            background-color: palevioletred;
        }
        
        #box .current,
        #box1 .current {
            display: block;
            background-color: palegreen;
        }
    </style>
</head>

<body>
    <div id="box">
        <section>
            <button class="active">娱乐</button>
            <button>体育</button>
            <button>教育</button>
        </section>
        <section>
            <div class="current">娱乐</div>
            <div>体育</div>
            <div>教育</div>
        </section>
    </div>

    <hr>
    <div id="box1">
        <section>
            <button class="active">娱乐</button>
            <button>体育</button>
            <button>教育</button>
        </section>
        <section>
            <div class="current">娱乐</div>
            <div>体育</div>
            <div>教育</div>
        </section>
    </div>
</body>
<script>
    //构造函数
    function Tab(ele, type) {
        this.ele = document.querySelector(ele); // {ele:"元素"}
        this.btns = this.ele.children[0].children
        this.divs = this.ele.children[1].children
        this.changeColor(type); // 函数的调用  "click"
    }
    Tab.prototype.changeColor = function(type) {
            // this: 指向的是实例化对象的this
            for (let i = 0; i < this.btns.length; i++) {
                this.btns[i].addEventListener(type, () => {
                    console.log(2);
                    // this.btns[i]:i就可以用了,this.btns[i]代表具体点击的元素
                    for (var j = 0; j < this.btns.length; j++) {
                        this.btns[j].classList.remove("active")
                        this.divs[j].classList.remove("current")
                    }
                    this.btns[i].classList.add("active")
                    this.divs[i].classList.add("current")
                })
            }
        }
        // 创建对象
    let tab1 = new Tab("#box", "click")
    let tab2 = new Tab("#box1", "mouseover")

</script>

</html>

 

五、class类

从ES6开始,JavaScript引入了类(class)的语法,可以用来创建构造函数。这种语法更加简洁和清晰。

    //写法一: 构造函数
    function Person(name, age) {
        this.name = name;   
        this.age = age;   
    }
    Person.prototype.say = function () {
        console.log("呵呵");
    }
    let p1 = new Person("zs", 10)
    let p2 = new Person("zs", 10)
    console.log(p1);
    console.log(p1 == p2); // false

    //写法二: class类的写法
    class Person {
        constructor(name, age) {
            this.name = name;
            this.age = age;
        }
        //相当于挂载在了构造函数的原型对象上, Person.prototype.say = function(){}
        say() {  
            console.log("呵呵");
        }
    }
    let p1 = new Person("zs", 10)
    let p2 = new Person("zs", 10)
    console.log(p1);
    console.log(p1 == p2); // false
选项卡(class类写法) 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #box div,
        #box1 div {
            width: 200px;
            height: 50px;
            background-color: palegreen;
            display: none;
        }
        
        .active {
            background-color: palevioletred;
        }
        
        #box .current,
        #box1 .current {
            display: block;
            background-color: palegreen;
        }
    </style>
</head>

<body>
    <div id="box">
        <section>
            <button class="active">娱乐</button>
            <button>体育</button>
            <button>教育</button>
        </section>
        <section>
            <div class="current">娱乐</div>
            <div>体育</div>
            <div>教育</div>
        </section>
    </div>

    <hr>
    <div id="box1">
        <section>
            <button class="active">娱乐</button>
            <button>体育</button>
            <button>教育</button>
        </section>
        <section>
            <div class="current">娱乐</div>
            <div>体育</div>
            <div>教育</div>
        </section>
    </div>
</body>
<script>
    // class类
    class Tab {
        constructor(ele, type) {
            this.ele = document.querySelector(ele); // {ele:"元素"}
            this.btns = this.ele.children[0].children
            this.divs = this.ele.children[1].children
            this.changeColor(type); // 函数的调用  "click"
        }
        changeColor(type) {
            for (let i = 0; i < this.btns.length; i++) {
                this.btns[i].addEventListener(type, () => {
                    console.log(2);
                    // this.btns[i]:i就可以用了,this.btns[i]代表具体点击的元素
                    for (var j = 0; j < this.btns.length; j++) {
                        this.btns[j].classList.remove("active")
                        this.divs[j].classList.remove("current")
                    }
                    this.btns[i].classList.add("active")
                    this.divs[i].classList.add("current")
                })
            }
        }
    }
    let tab1 = new Tab("#box", "click")
    let tab2 = new Tab("#box1", "mouseover")
</script>

</html>

 六、继承

      发生在两个构造函数之间,如果说A构造函数使用了B构造函数中的属性或者方法,A继承自B,B就属于父类,A属于子类

      可以把构造函数当成一个类

1.借用父类构造函数继承

优点:可以继承父类构造函数内的属性和方法 ​ 缺点:不可以继承父类原型对象上的属性和方法

    // 定义父类构造函数
    function Father(name, age) {
        this.name = name;
        this.age = age;
    }
    // 父类原型方法
    Father.prototype.sayHello = function() {
        console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
    };

    // 定义子类构造函数
    function Child(name, age, grade) {
        // 借用父类构造函数
        Father.call(this, name, age); // 通过call()借用父类构造函数
        this.grade = grade; // 子类特有的属性
    }

    // 使用示例
    const child = new Child('Alice', 10, 5); //{name: 'Alice', age: 10, grade: 5}
    child.sayHello(); //  child.sayHello is not a function

2.原型链继承

优点:可以继承父类原型对象上的属性和方法 ​ 缺点:不可以继承父类构造函数内的属性和方法

 

    // Father类
    function Father(money) {
        this.money = money
    }
    Father.prototype.smoke = function() {
            console.log("吸烟");
        }
    // Son类
    function Son(name, money) {
        this.name = name;
    }
    Son.prototype = new Father(); // 会覆盖掉Son构造函数原型对象的constructor属性
    Son.prototype.constructor = Son; // 手动加上
    Son.prototype.study = function() {
        console.log("study");
    }

    var f = new Father(10000)
    var s = new Son("小张")
    console.log(s);
    s.smoke();
 3.组合继承

优点:实现函数复用,保证每个实例之间的属性不会相互影响。 ​

缺点:使用了两次继承,代码书写繁琐,还出现了constructor的覆盖

    // Father类
    function Father(money) {
        this.money = money
    }
    Father.prototype.smoke = function() {
            console.log("吸烟");
        }

    // Son类
    function Son(name, money) {
        this.name = name;
        Father.call(this, money); // 继承父类属性的关键
    }
    Son.prototype = new Father(); // 继承父类原型对象方法的关键
    Son.prototype.study = function() {
        console.log("study");
    }

    var s = new Son("小张", 1000); // 即继承了属性
    console.log(s);
    s.smoke(); // 又继承了父类原型对象上的方法
4.es6继承:extends super

优点:1.既可以继承父类的属性,也可以继承父类原型对象上的方法 ​ 2.写法简单

 

    class Father {
        constructor(money) {
            this.money = money;
        }
        smoke() {
            console.log('抽大烟');
        }
    }
    class Son extends Father {
        constructor(name, money) {
            super(money);
            this.name = name;
        }
    }
    // extends来继承父类的属性和方法,必须还需要使用 super()访问父类的构造器(构造器的代码走一遍)
    var son = new Son("小明", 10000)
    console.log(son);
    son.smoke()

    // 既可以继承父类的属性,也可以继承父类原型对象上的方法

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

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

相关文章

【react 和 vue】 ---- 实现组件的递归渲染

1. 需求场景 今天遇到了一个需求&#xff0c;就是 HTML 的递归渲染。问题就是商品的可用时间&#xff0c;使用规则等数据是后端配置&#xff0c;然后配置规则则是可以无限递归的往下配置&#xff0c;可以存在很多级。后端实现后&#xff0c;数据返回前端&#xff0c;就需要前端…

【mysql 进阶】2-1. MySQL 服务器介绍

MySQL 服务器简介 通常所说的 MySQL 服务器指的是mysqld程序&#xff0c;当运⾏mysqld后对外提供MySQL 服务&#xff0c;这个专题的内容涵盖了以下关于MySQL 服务器以及相关配置的内容&#xff0c;包括&#xff1a; 服务器⽀持的启动选项。可以在命令⾏和配置⽂件中指定这些选…

前后端请求、返回数据的多种方式

Springboot项目的业务逻辑 &#x1f319;项目基本结构&#xff1a; 通常情况下&#xff0c;我们在搭建后端项目的时候&#xff0c;处理业务逻辑我们需要用到Controller,Service,Mapper(mybatis,mybatis-plus)&#xff0c;Entry各层之间的相互调用来完成&#xff0c;还有就是我…

数据库->增删改查

目录 一、CRUD简介 二、Create新增 1.单行数据插入 2.查询 3. 多行数据插入 4.执行本机的SQL脚本插入 三、Retrieve检索 1.全列查询 2.指定列查询 3.查询字段为表达式 3.1 常量表达式 3.2列的值与常量运算 3.3列与列之间的运算 3.4为列指定别名 4.结果查询去重…

高等数学-宋浩版2.0-映射

映射&#xff1a;X,Y为非空集合&#xff0c;存在法则F,对X(原像)中每个元素X&#xff0c;按法则F&#xff0c;在Y中有唯一元素与之对应&#xff0c;F为x到Y&#xff08;镜像&#xff09;的映射。f:X->Y X原像&#xff0c;Y像&#xff0c;x定义域&#xff0c;Df,Rf &#x…

php后端学习,Java转php

遇到前后端跨域 php解决跨域问题可以加上下面的代码&#xff1a; header(“Access-Control-Allow-Origin:*”); 并且查看自己的数据库信息是否连接成功。 从Java转php 个人感受php跟偏向前端&#xff0c; 写后端逻辑时没有像java又springboot工具方便。 但是和前端联调很方便…

BUUCTF之web篇

第一题 [极客大挑战 2019]EasySQL 打开靶机后可以看到这是一个登陆的页面 我们可以尝试两种方式登录 弱口令爆破&#xff08;burpsuite&#xff09; 通过SQL注入里的万能密码来跳过账户和密码验证的过程 这里就需要万能密码aor true # 在这里单引号的作用是结束用户名或者密码…

Python基于TensorFlow实现简单循环神经网络回归模型(SimpleRNN回归算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后关注获取。 1.项目背景 Simple RNN是一种基础的循环神经网络&#xff0c;它能够处理序列数据&#xff0c;例如文本、时间序…

React写关键字高亮的三个方案

1.js正则replaceAlldangerouslySetInnerHTML{{ __html: xxx }}危险属性 步骤最简单,但是是危险属性,不推荐使用,项目中实在没有头绪,可以使用它应急 通过useMemo计算得到新的状态值,赋值给dangerouslySetInnerHTML属性的__html 关键代码: const [state1, setState1] useSt…

【网络原理】网络地址转换----NAT技术详解

&#x1f490;个人主页&#xff1a;初晴~ &#x1f4da;相关专栏&#xff1a;计算机网络那些事 我们在 IP协议 一文中介绍过&#xff0c;由于IPv4协议中 IP地址只有32位&#xff0c;导致最多只能表示 42亿9千万个IP地址。但我们需要通过IP地址来标识网络上的每一个设备&#x…

java核心技术点都有哪些

1. 面向对象编程&#xff08;OOP&#xff09; 核心概念&#xff1a;类、对象、继承、封装、多态。 比喻&#xff1a;面向对象编程就像是在搭建一个积木城堡。类&#xff08;Class&#xff09;是城堡的设计图纸&#xff0c;它定义了城堡的结构和功能&#xff1b;对象&#xff08…

传输层TCP

报头 1.报头和有效载荷如何分离将&#xff0c;有效载荷向上交付&#xff1f; tcp有个标准报头长度为20&#xff0c;那是不是以为我们可以像udp一样分离依靠报头大小去分离&#xff0c;我们仔细去看我们报头中还有个选项没包含到。 我们还有个首部长度&#xff0c;四位可以表…

测试代理IP的有效性和可用性

使用代理IP的有效性和可用性直接关系到用户的工作效率&#xff0c;尤其是在进行数据抓取、网络爬虫和保护个人隐私等场景中。 一、测试代理IP的必要性 代理IP的可用性测试是确保代理服务正常运行的重要步骤。测试代理IP的必要性主要体现在以下几个方面&#xff1a; 提升工作…

【Docker命令】日常使用的Docker命令

Docker常用命令 1、基础命令2、容器管理3、镜像管理推送镜像 4、网络管理5、数据管理 1、基础命令 - docker run&#xff1a;运行一个容器,--name 指定容器的名称&#xff0c;-i 获取标准输入输出&#xff0c;-t显示在终端&#xff0c;-d放到后台运行&#xff0c;--rm容器停止…

STM32传感器模块编程实践(十) 2.4G NRF24L01通信模块简介及驱动源码

文章目录 一.概要二.NRF24L01模块介绍三.NRF24L01模块主要特性四.国产射频芯片SI24R1介绍五.模块接线说明六.参考原理图七.通讯协议介绍八.STM32单片机与NRF24L01模块实现远无线通讯实验1.硬件准备2.软件工程3.软件主要代码4.实验效果 九.源代码工程下载十.小结 一.概要 NRF24…

InnoDB 存储引擎<二>页结构和行结构

目录 ⻚结构 ⾏结构 ⻚结构 ⻚在MySQL运⾏的过程中起到了⾮常重要的作⽤&#xff0c;为了能发挥更好的性能&#xff0c;可以结合⾃⼰系统的 业务场景和数据⼤⼩&#xff0c;对⻚相关的系统变量进⾏调整&#xff0c;⻚的⼤⼩就是⼀个⾮常重要的调整项 1.⻚的⼤⼩可以设置吗&…

RHCSA笔记一

常见的操作系统 UNIX 、 Linux 类、 Windows 类 搭建Linux学习环境 如何安装linux操作系统&#xff1a; 安装独立的 Linux 系统&#xff0c;不再安装其他操作系统。 安装 Windows 与 Linux 并存的多操作系统&#xff0c;启动时通过菜单选择要启动的操作系统。 在虚拟机中安…

十一、数据库配置

一、Navicat配置 这个软件需要破解 密码是&#xff1a;123456&#xff1b; 新建连接》新建数据库 创建一个表 保存出现名字设置 双击打开 把id设置为自动递增 这里就相当于每一次向数据库添加一个语句&#xff0c;会自动增长id一次 二、数据库的增删改查 1、Vs 建一个控…

探索华为云DataArts Insight:数据智能的新引擎

在快速发展的数字化时代&#xff0c;数据已经成为企业最宝贵的资产。如何有效地管理和利用这些数据&#xff0c;以实现商业价值&#xff0c;是每个企业需要面对的重要挑战。华为云DataArts Insight平台应运而生&#xff0c;作为一款强大的数据智能解决方案&#xff0c;它帮助企…

Kotlin-Annotations详解

在Kotlin中&#xff0c;注解&#xff08;Annotations&#xff09;是用于为代码提供元数据的一种机制。这些元数据可以被编译器、IDE&#xff08;集成开发环境&#xff09;或其他工具使用&#xff0c;以生成代码、执行编译时检查或提供运行时信息。 注解通常被用于类、方法、属…