JavaScript高级 —— 学习(三)

news2024/11/21 1:25:38

目录

一、深入面向对象

(一)面向对象介绍

(二)面向对象编程 (oop)

1.面向对象编程介绍

2.面向对象编程优点

3.面向对象的特征

4.和面向过程编程对比

二、构造函数

(一)介绍

 (二)内存浪费

三、原型

(一)原型介绍

(二)constructor 属性

(三)对象原型

1.介绍

2.三者关系图

(四)原型继承

1.简单使用对象继承(有问题)

2.使用父构造函数继承

(五)原型链

1.原型链介绍

2.模型图讲解

3.原型链面试理解

练习:给数组拓展求最大最小值和求和方法

综合案例:模态框构造函数


一、深入面向对象

分为面向过程和面向对象两种,面向过程是以步骤来划分问题,在这儿不做过多描述。

(一)面向对象介绍

把事务分解成一个个对象,由对象之间分工合作,面向对象是以对象功能来划分问题,

(二)面向对象编程 (oop)

1.面向对象编程介绍

就是事情没有先后顺序,是并行进行的,每个对象都是功能中心,必须有明确分工。

2.面向对象编程优点

面向对象编程 灵活 容易维护和开发 适合多人合作大型软件项目

3.面向对象的特征

封装性

继承性

多态性

4.和面向过程编程对比

二、构造函数

(一)介绍

封装在面向对象编程中很重要,js 面向对象可以通过构造函数实现封装

构造函数体现了面向对象的封装特性

使用构造函数创建的对象彼此独立,互不影响

下面的 this 就是指向下面创建的对象 zhangsan

再创建一个别的指向就不同了 所以相互独立

<body>
  <script>
   function Person(name, age){
    this.name = name
    this.age = age 
   }
  const zhangsan = new Person('张三', 18)
  console.log(zhangsan)
  </script>
</body>

 (二)内存浪费

构造函数 存在内存浪费的问题,张三和李四的吃饭方法都是相同的但是它们分别属于不同的对象,所以不相等,所以会浪费内存

<body>
  <script>
   function Person(name, age){
    this.name = name
    this.age = age 
    this.eat = function(){
      console.log('我是人')
    }
   }
  const zhangsan = new Person('张三', 18)
  const lisi = new Person('李四', 20)
  console.log(zhangsan.eat === lisi.eat)
  </script>
</body>

三、原型

(一)原型介绍

用于解决构造函数内存浪费的问题,利用原型实现方法共享,原型分配的函数是所有对象共享的

每个构造函数都有一个 prototype 属性 原型在构造函数中,是一个对象,叫原型对象

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

就是把公共的方法单独拿出来 使用 构造函数名.prototype.方法名 = ...   就不会多次创建浪费内存了

公共属性放构造函数里面就行

<body>
  <script>
    function Person(name, age) {
      this.name = name
      this.age = age
    }
    Person.prototype.eat = function () {
      console.log('吃吃吃')
    }
    const zhangsan = new Person('张三', 18)
    const lisi = new Person('李四', 20)
    console.log(zhangsan.eat === lisi.eat)
  </script>
</body>

原型对象中的 this 也指向 实例化后的对象 zhangsan,和构造函数中的 this 指向相同

<body>
  <script>
    function Person(name, age) {
      this.name = name
      this.age = age
    }
    Person.prototype.eat = function () {
      that = this
      console.log('吃吃吃')
    }
    const zhangsan = new Person('张三', '18')
    zhangsan.eat()
    console.log(zhangsan === that)
  </script>
</body>

(二)constructor 属性

 每个原型对象都有 constructor 属性,这个属性指向原型对象 (prototype)的构造函数

如果有多个对象方法,可以给构造函数的原型对象赋值,来节省内存

原本 prototype 是一个对象 并通过 constructor 指向它的构造函数父亲 Person 但是经过给原型对象赋值后 覆盖了之前的 原型对象,之前能指向父亲的 constructor 属性消失了 所以就失去父亲了 这个原型对象就不知道是谁的儿子了

所以我们需要在赋值的大括号里面重新加上 constructor 属性 就能指向原来的父亲了就能正常调用里面的方法了

<body>
  <script>
    function Person(name, age) {
      this.name = name
      this.age = age
    }
    Person.prototype = {
      constructor: Person,
      sing: function () {
        console.log("唱歌")
      },
      dance: function () {
        console.log('跳舞')
      }
    }
    console.log(Person.prototype.constructor)
  </script>
</body>

(三)对象原型

1.介绍

构造函数中有原型对象,构造函数也能创建实例对象,正常来说,原型对象和实例对象是同等地位的,那么怎么实例对象可以调用原型对象中的方法呢?

当然是因为对象原型,对象都会有一个属性 __proto__ 指向构造函数的原型对象 prototype ,所以实例对象能调用原型对象中的方法(一边是两个下划线)

__proto__ 不是 js 标准写法 [[prototype]] 是一个意思表明 当前实例对象指向 某个原型对象

下面两个布尔值是相等的

<body>
  <script>
    function Person(){}
    const zhangsan = new Person()
    console.log(zhangsan.__proto__ === Person.prototype)
  </script>
</body>
2.三者关系图

构造函数里本来就有 prototype 原型对象

构造函数能实例化实例对象

原型对象中有 constructor 属性指向 他的父亲构造函数

实例对象中 __proto__ 对象原型中的 constructor 属性也指向 父亲构造函数

实例对象的 对象原型 __proto__ 指向兄弟 原型对象 所以能调用其中的方法

 

(四)原型继承

1.简单使用对象继承(有问题)

如果有多个构造函数内部有很多相同的属性和方法,就可以再写一个对象把共同的部分单独提出来再用构造函数的原型对象继承

如下 男人女人 都具有人类的属性就把 人类属性单独提炼出来变成一个对象,然后前面学过如果是构造函数公用的部分,就得把相同的部分封装在原型对象中

所以把 Woman 和 Man 中的 prototype 用 Person 覆盖 这样就继承了Person的属性和方法,这样就能使用了,但是他俩都使用了Person 如果想要 添加各自单独的方法,就会污染 Person 对象

结果就是 在Woman 中创建的方法 在 Man 中 也能使用,因为他俩都继承了 Person ,都指向Person

<body>
  <script>
    const Person = {
      eyes: 2,
      head: 1
    }
    function Woman() {

    }
    function Man() {

    }
    Woman.prototype = Person
    Woman.prototype.contructor = Woman
    Woman.prototype.baby = function () {
      console.log('宝贝')
    }
    Man.prototype = Person
    Man.prototype.contructor = Man
    const zhangsan = new Woman()
    const lisi = new Man()
    console.log(lisi.baby())
  </script>
</body>
2.使用父构造函数继承

为了解决上面的问题,我们只要让每个构造函数的原型对象 被赋值的 Person 不一样就行了

就是

Man.prototype = Person1

Woman.prototype = Person2

就避免了上面的情况,因为现在 他俩指向的 Person 不同了,这样就不会互相影响了

思路就是把 数组 Person 也变成一个构造函数 然后每次 new Person() 都不一样就可以出现不一样的Person 对象了

改进代码如下:这样 lisi 就不具有 baby() 方法了

<body>
  <script>
    function Person() {
      eyes = 2
      head = 1
    }
    function Woman() {

    }
    function Man() {

    }
    Woman.prototype = new Person()
    Woman.prototype.contructor = Woman
    Woman.prototype.baby = function () {
      console.log('宝贝')
    }
    Man.prototype = new Person()
    Man.prototype.contructor = Man
    const zhangsan = new Woman()
    const lisi = new Man()
    console.log(zhangsan.baby())
  </script>
</body>

(五)原型链

1.原型链介绍

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

只要是对象就有 __proto__,__proto__ 只指向原型对象 prototype

只要有原型对象就有 constructor,指向创建我的 构造函数

2.模型图讲解

__proto__ 就构成了原型链

基本的三角关系不过多描述了,前面有

实例对象 中有对象原型 __proto__ 指向 兄弟:父亲构造函数的原型对象 prototype

但是兄弟原型对象也是对象 也拥有对象原型 __proto__ 它指向的是更大的爷爷

就是 构造函数 Object 的原型对象 Object.prototype

Object.prototype 也能指向 Object 通过 Object.prototype.constructor 指向

但是原型对象 Object.prototype 也是对象也拥有对象原型 __proto__  但是没有更大的构造函数了,所以最后指向为 空 null 原型链就结束了

3.原型链面试理解

类似于作用域链

1.原型链就是一种查找规则,我们想要一些属性和方法,先看当前实例有没有当前方法

2.如果没有就查找它的原型 __proto__ 指向的 prototype 原型对象

3.如果还没有 就查找原型对象的原型

4.直到查到 null (Object)为止

__proto__ 原型对象为对象成员查找机制提供了一个方向/一条路路线

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

下面三个输出结果都是 true

Object 是最大的对象 数组也是对象 本质也是通过 const str = new Array() 出来的

<body>
  <script>
    const str = [1,2,3]
    function Person(){

    }
    const zhangsan = new Person()
    console.log(str instanceof Array)
    console.log(zhangsan instanceof Person)
    console.log(zhangsan instanceof Object)
  </script>
</body>

练习:给数组拓展求最大最小值和求和方法

结果展示:

代码部分:

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

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    const arr = [1, 2, 3]
    Array.prototype.max = function () {
      return Math.max(...this)
    }
    Array.prototype.min = function () {
      return Math.min(...this)
    }
    Array.prototype.sum = function () {
      return this.reduce((prev, item) => prev + item, 0)
    }
    console.log(arr.max())
    console.log(arr.min())
    console.log(arr.sum())

  </script>
</body>

</html>

综合案例:模态框构造函数

界面展示:

代码部分:

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

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .modal {
      width: 300px;
      min-height: 100px;
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
      border-radius: 4px;
      position: fixed;
      z-index: 999;
      left: 50%;
      top: 50%;
      transform: translate3d(-50%, -50%, 0);
      background-color: #fff;
    }

    .modal .header {
      line-height: 40px;
      padding: 0 10px;
      position: relative;
      font-size: 20px;
    }

    .modal .header i {
      font-style: normal;
      color: #999;
      position: absolute;
      right: 15px;
      top: -2px;
      cursor: pointer;
    }

    .modal .body {
      text-align: center;
      padding: 10px;
    }

    .modal .footer {
      display: flex;
      justify-content: flex-end;
      padding: 10px;
    }

    .modal .footer a {
      padding: 3px 8px;
      background: #ccc;
      text-decoration: none;
      color: #fff;
      border-radius: 2px;
      margin-right: 10px;
      font-size: 14px;
    }

    .modal .footer a.submit {
      background-color: #369;
    }
  </style>
</head>

<body>
  <button id="delete">删除</button>
  <button id="login">登录</button>
  <script>
    function Modal(title = '', message = '') {
      this.box = document.createElement('div')
      this.box.className = 'modal'
      this.box.innerHTML = `<div class="header">${title}<i>×</i></div>
    <div class="body">${message}</div>`
    }
    Modal.prototype.open = function () {
      const panduan = document.querySelector('.modal')
      panduan && panduan.remove()
      document.body.append(this.box)
      this.box.querySelector('i').addEventListener('click', () => {
        this.close()
      })
    }
    Modal.prototype.close = function () {
      this.box.remove()
    }
    document.querySelector('#delete').addEventListener('click', () => {
      const del = new Modal('温馨提示', '没有权限删除权限')
      del.open()
    })
    document.querySelector('#login').addEventListener('click', () => {
      const login = new Modal('友情提示', '你没注册')
      login.open()
    })
  </script>
</body>

</html>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32 移植 LVGL -- 教程图解

&#xff08; 编辑状态中&#xff0c;已完成80%&#xff0c;估计清明假期后完成更新 ) 移植效果&#xff0c;先睹为快&#xff1a; 目录 一、LVGL 简述 二、准备一个STM32的工程 三、LVGL 官方下载 四、裁剪 源文件 五、添加 源文件 六、注册 显示 七、注册 触摸输入 八…

014——超声波模块驱动开发Plus(基于I.MX6uLL、SR04和poll机制)

目录 一、基础知识 二、分析为什么打印会影响中断 三、驱动程序 四、应用程序 五、验证及其它 一、基础知识 013——超声波模块驱动开发&#xff08;基于I.MX6uLL与SR04&#xff09;-CSDN博客 二、分析为什么打印会影响中断 asmlinkage __visible int printk(const ch…

如何在本地搭建集成大语言模型Llama 2的聊天机器人并实现无公网IP远程访问

文章目录 1. 拉取相关的Docker镜像2. 运行Ollama 镜像3. 运行Chatbot Ollama镜像4. 本地访问5. 群晖安装Cpolar6. 配置公网地址7. 公网访问8. 固定公网地址 随着ChatGPT 和open Sora 的热度剧增,大语言模型时代,开启了AI新篇章,大语言模型的应用非常广泛&#xff0c;包括聊天机…

Python字典操作

假设我们有一个学生信息数据库&#xff0c;其中存储了每个学生的姓名、年龄、性别和成绩。我们可以使用字典来表示每个学生的信息&#xff0c;并将所有学生存储在一个字典列表中。 设计者&#xff1a;ISDF 版本&#xff1a;v1.0 日期&#xff1a;03/29/2024# 定义学生信息字典列…

Ruby 之交租阶段信息生成

题目 我看了一下&#xff0c;这个题目应该不是什么机密&#xff0c;所以先放上来了。大概意思是根据合同信息生成交租阶段信息。 解答 要求是要使用 Ruby 生成交租阶段信息&#xff0c;由于时间比较仓促&#xff0c;变量名那些就用得随意了些。要点主要有下面这些&#xff1a…

高级IO/多路转接-select/poll(1)

概念背景 IO的本质就是输入输出 刚开始学网络的时候&#xff0c;我们简单的写过一些网络服务&#xff0c;其中用到了read&#xff0c;write这样的接口&#xff0c;当时我们用的就是基础IO&#xff0c;高级IO主要就是效率问题。 我们在应用层调用read&&write的时候&…

八、从0开始卷出一个新项目之瑞萨RZN2L 3.1.7 debug调试和下载

目录 3.1.7 debug调试和下载 3.1.7.1 官方介绍 3.1.7.2 e2studio debug变量实时监控 3.1.7.3 Iar debug变量实时监控 3.1.7.4 debug经验总结 八、从0开始卷出一个新项目之瑞萨RZN2L 3.1.7 debug调试和下载 3.1.7 debug调试和下载 3.1.7.1 官方介绍 官网&#xff1a; d…

day02-java类型转换和运算符

1.温故而知新 整形 byte 1字节 8位 short 2字节 16位 int 4字节 32位 long 8字节 64位 内存存储时 X符号位 byte X0000000 short X0000000 00000000 int X0000000 00000000 00000000 long X0000000 00000000 00000000 00000000 long longNum 10000L;//l或者L 查看源码最大值…

数据库之迁移常规操作(Mysql篇)

借鉴的文章 》》https://blog.csdn.net/weixin_65685029/article/details/132413482?ops_request_misc&request_id&biz_id102&utm_termmysql备份与还原&utm_mediumdistribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-132413482.nonecase…

C语言 | Leetcode C语言题解之第6题Z字形变换

题目&#xff1a; 题解&#xff1a; char * convert(char * s, int numRows){int n strlen(s), r numRows;if (r 1 || r > n) {return s;}int t r * 2 - 2;char * ans (char *)malloc(sizeof(char) * (n 1));int pos 0;for (int i 0; i < r; i) { // 枚举矩阵的…

语言模型进化史(下)

由于篇幅原因&#xff0c;本文分为上下两篇&#xff0c;上篇主要讲解语言模型从朴素语言模型到基于神经网络的语言模型&#xff0c;下篇主要讲解现代大语言模型以及基于指令微调的LLM。文章来源是&#xff1a;https://www.numind.ai/blog/what-are-large-language-models 四、现…

Multi-Head Attention 代码实现

Multi-Head Attention 代码实现 flyfish MultiHead ( Q , K , V ) Concat ( head 1 , . . . , head h ) W O \text{MultiHead}(Q, K, V) \text{Concat}(\text{head}_1, ..., \text{head}_h)W^O MultiHead(Q,K,V)Concat(head1​,...,headh​)WO head i Attention ( Q W i Q…

kettle使用MD5加密增量获取接口数据

kettle使用MD5加密增量获取接口数据 场景介绍&#xff1a; 使用JavaScript组件进行MD5加密得到Http header&#xff0c;调用API接口增量获取接口数据&#xff0c;使用json input组件解析数据入库 案例适用范围&#xff1a; MD5加密可参考、增量过程可参考、调用API接口获取…

C++(set和map详解,包含常用函数的分析)

set set是关联性容器 set的底层是在极端情况下都不会退化成单只的红黑树,也就是平衡树,本质是二叉搜索树. set的性质:set的key是不允许被修改的 使用set需要包含头文件 set<int> s;s.insert(1);s.insert(1);s.insert(1);s.insert(1);s.insert(2);s.insert(56);s.inser…

面试题:RabbitMQ 消息队列中间件

1. 确保消息不丢失 生产者确认机制 确保生产者的消息能到达队列&#xff0c;如果报错可以先记录到日志中&#xff0c;再去修复数据持久化功能 确保消息未消费前在队列中不会丢失&#xff0c;其中的交换机、队列、和消息都要做持久化消费者确认机制 由spring确认消息处理成功后…

Java基础之流程控制语句(循环)

文章目录 Java基础之流程控制语句(循环)1.顺序结构2.分支结构if语句的第一种格式if语句的第二种格式if语句的第三种格式Switch语句格式Switch的其他知识点default的位置和省略case穿透Switch的新特性 3.循环结构循环的分类for 循环while 循环for循环 与 while循环 的对比 4.do.…

RAG原理、综述与论文应用全解析

1. 背景 1.1 定义 检索增强生成 (Retrieval-Augmented Generation, RAG) 是指在利用大语言模型回答问题之前&#xff0c;先从外部知识库检索相关信息。 早在2020年就已经有人提及RAG的概念&#xff08;paper&#xff1a;Retrieval-augmented generation for knowledge-inten…

IDEA 解决 java: 找不到符号 符号: 类 __ (使用了lombok的注解)

原因IDEA版本太高&#xff0c;在 ProcessingEnvironement 预编译的时候是以代理的方式来执行的&#xff0c;不再是直接 javac方式, lombok依赖的 javac方式的 annotation processors 不再生效了 解决办法&#xff1a;下面这一句&#xff0c;加在下图中 -Djps.track.ap.depen…

八口快速以太网交换机芯片方案分享/JL5110

以太网交换机(switch)是一种网络设备&#xff0c;用于在局域网中连接多个计算机和其他网络设备。它可以实现多个端口之间的同时传输&#xff0c;并根据MAC地址进行帧过滤和转发。交换机通过自学习的方式&#xff0c;将MAC地址与相应的接口关联起来&#xff0c;以便将数据帧准确…

C语言中的数组与函数指针:深入解析与应用

文章目录 一、引言二、数组的定义1、数组的定义与初始化2、char*与char[]的区别1. 存储与表示2. 修改内容3. 作为函数参数 三、字符串指针数组1. 定义与概念2. 使用示例3. 内存管理 四、从字符串指针数组到函数指针的过渡1、字符串指针数组的应用场景2、函数指针的基本概念3、如…