JavaScript进阶--深入面向对象

news2024/11/24 23:02:01

深入面向对象

编程思想

  • 面向过程:多个步骤=> 解决问题

    性能较高,适合跟硬件联系很紧密的东西,如单片机

    但代码维护成本高,扩展性差

  • 面向对象:问题所需功能分解为一个一个的对象(分工合作)=> 接口

    明确分工,灵活,代码可复用,容易维护和开发,适合大型软件项目

    但性能较低

[!NOTE]

前端面向过程的代码较多

构造函数实现封装

==> 存在浪费内存问题【若属性,方法相同,则多存一个实例化对象,就会多浪费内存空间】

 function Pig(name, age) {
      this.name = name;
      this.age = age;
    };
    const jogh = new Pig('jogh', 10);
    console.log(jogh.name);
    console.log(jogh.age);

原型对象 prototype

构造函数.prototype.方法名 = function(){...}

相当于构造函数中的一个属性

解决构造函数相同的成员造成的空间浪费

图解:

在这里插入图片描述

let that;
    function Pig(name, age) {
      this.name = name;
      this.age = age;
      that = this;
      console.log(that);
    };
    Pig.prototype.eat = function () {
      console.log("eat food");
      that = this;
      console.log(that);
    }
    const jogh = new Pig('jogh', 10);
    jogh.eat();

[!IMPORTANT]

构造函数和prototype的this都指向实例化对象

给数组扩展方法

通过原型prototype来拓展数组方法

//通过原型prototype来拓展数组方法
    //最大值
    Array.prototype.max = function () {
      return Math.max(...this);
    }
    //求和
    Array.prototype.sum = function () {

      return this.reduce((pre, cur) => pre + cur, 0);
    }
    //技巧:this就是指向实例对象的,所以不需要在把数组传进去方法中去

    //测试能否正常调用
    const arr1 = [1, 2, 3, 4, 5];
    const arr2 = [1, 5, 8, 3, 2];
    console.log(arr1.max());
    console.log(arr1.sum());
    console.log(arr2.max());
    console.log(arr2.sum());

constructor属性及其应用

==> 指向构造函数 【prototype中的一个属性】

应用

当对prototype整体赋值时,会丢失指向构造函数的路径,需用constructor来重新指向构造函数

function Pig(name, age) {
      this.name = name;
      this.age = age;
    };
    console.log(Pig.prototype);

    Pig.prototype = {
      sing: function () {
        console.log("sing");
      },
      dance: function () {
        console.log("dance");
      }
    };
    console.log(Pig.prototype);

图解

在这里插入图片描述

对象原型 __proto__

每个实例化对象都有的属性(只读)

==> 指向构造函数中的原型对象

注意

  • JS非标准属性
  • [prototype]__proto__意义相同
  • 也有constructor属性,指向构造函数

因为有了对象原型,实例化对象才可以直接调用原型对象中的方法

 function Pig(name, age) {
      this.name = name;
      this.age = age;
    };
    console.log(Pig.prototype);
    const jogh = new Pig('jogh', 10);
    console.log(jogh.__proto__);
    console.log(jogh.__proto__.constructor);
    console.log(Pig.prototype.constructor);

图解:

在这里插入图片描述

原型继承

通过原型对象来继承一个实例化对象中的内容,本质是,创建一个需要被继承的实例化对象,然后原型对象保存了指向这个空间的地址,最后需要将constructor重新指向对应的构造函数

//如果是通过一个实例化对象进行继承的话,如果继承的对象后续想给自己的原型对象中加点属性或方法,会导致所有的继承对象的原型对象都发生变化
    //原因:每个继承的对象的原型对象指向的是同一个实例化对象,也就是在栈中保存的是相同的地址
    //男人和女人
    function Man() {

    }
    //通过原型对象进行继承
    Man.prototype = new Person();
    //得重新指向构造函数
    Man.prototype.constructor = Man;
    Man.prototype.sing = function () {
      console.log("sing");
    }
    console.log(Man.prototype);
    console.log(new Man().__proto__.constructor);


    function Woman() {

    }
    //通过原型对象进行继承
    Woman.prototype = new Person();
    //得重新指向构造函数
    Woman.prototype.constructor = Woman;
    Woman.prototype.born = function () {
      console.log("baby");
    }
    console.log(Woman.prototype);
    console.log(new Woman().__proto__.constructor);

原型链

面试常考

由于原型对象的继承,使得不同构造函数的原型对象关联在一起 => 关系酷似链式解构,因此得名

[!IMPORTANT]

一种查找规则,当调用一个对象的成员时,先找自身==> 找不到则找自身的原型对象=>找不到则找自身原型对象的对象原型

一直找到Object.prototype为止

在这里插入图片描述

instanceof

判断某个实例化对象或者一个构造函数是否在Object的原型链上

function Person() {
      this.eyes = 2;
    }
    console.log(Person.prototype.__proto__ === Object.prototype);
    console.log(new Person().__proto__.__proto__ === Object.prototype);

    console.log(Person instanceof Object);
    console.log(Person instanceof Array);
    console.log([1, 2, 3] instanceof Array);
    console.log(Array instanceof Object);

综合案例

通过面向对象的方法实现提示框的功能

同个提示框的功能可以给其他按钮复用,只需更改参数

  1. 一个构造函数创建一个标签,多样化通过实参进行传入
  2. 在原型对象prototype上挂载open和close
    • close:在body中删除这个标签
    • open先判断是否已经由同类型标签,有则移除,添加对象到body中,绑定关闭事件

3.按钮点击:实例化=>调用open

<!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>面向对象封装消息提示</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>

  <!-- <div class="modal">
    <div class="header">温馨提示 <i>x</i></div>
    <div class="body">您没有删除权限操作</div>
  </div> -->


  <script>
    //1.设置构造函数modal创建一个div
    function Modal(title = '', msg = '') {
      this.modal = document.createElement('div');
      this.modal.className = 'modal';
      this.modal.innerHTML = `
      <div class="header">${title} <i>x</i></div>
    <div class="body">${msg}</div>
      `
    }

    //2.封装打开函数到prototype中
    Modal.prototype.open = function () {
      const box = document.querySelector('.modal')
      box && box.remove();
      document.querySelector('body').appendChild(this.modal);
      //绑定点击关闭事件
      this.modal.querySelector('i').addEventListener('click', () => {
        this.close();
      })
    }
    //3.封装关闭函数到prototype中
    Modal.prototype.close = function () {
      document.querySelector('body').removeChild(this.modal)
    }
    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/2211719.html

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

相关文章

科研杂谈:24年诺奖颁布,AI竟是最终赢家?!

前言 2024年诺贝尔奖的公布引发了全球科学界的广泛关注&#xff0c;尤其是在人工智能&#xff08;AI&#xff09;领域的突破性获奖。诺贝尔物理学奖和化学奖相继颁给了在机器学习和蛋白质结构预测上取得重大进展的科学家们&#xff0c;让人们惊讶地看到AI正在迅速改变传统科研…

[Hbase]一 HBase基础

1. HBase简介 1.1 HBase定义 HBase数据模型的关键在于 稀疏、分布式、多维、排序 的映射。其中映射 map指代非关系型数据库的 key-Value结构。 1.2 HBase数据模型 1)Name Space 命名空间,类似于关系型数据库的database 概念,每个命名空间下有多个表。HBase 两个自…

【AI】AIGC浅析

引言 人工智能生成内容&#xff08;AIGC&#xff09;正迅速改变我们的生活、学习以及工作的方式。在计算机科学与技术领域、软件开发、大数据、智能网联汽车和车路云一体化行业&#xff0c;AIGC的应用已经成为行业发展的新动力。探讨AIGC对这些领域的影响、对职业技能需求的变化…

[Javase]封装、继承、多态与异常处理

文章目录 一、前言二、封装1、封装的思想2、封装代码层面的体现 三、继承1、继承的概念和好处2、继承代码层面的体现 四、多态1、多态的概念2、多态的好处和三要素2、多态代码层面的体现 五、异常处理1、try-catch-finally结构详解2、throw\throws 一、前言 本文章适合有一定面…

CMake 教程跟做与翻译 4

目录 添加一个option! 添加一个option! option&#xff0c;正如其意&#xff0c;就是选项的意思。我们这里需要演示一下option的做法。 option对于大型的工程必然是非常常见的&#xff1a;一些模块会被要求编译&#xff0c;另一些客户不准备需要这些模块。option就是将这种需…

【LLM KG】浅尝基于LLM的三阶段自动知识图谱构建方法

文章指出&#xff0c;在以前的方法中&#xff0c;使用LLM生成三元组时&#xff0c;必须预定义好schema&#xff0c;假如schema数量很多/复杂&#xff0c;很容易超过LLM的上下文窗口长度。并且&#xff0c;在某些情况下&#xff0c;没有可用的固定预定义schema。 方法 一、EDC…

计算机网络:数据链路层 —— 网络适配器与 MAC 地址

文章目录 网络适配器使用网络适配器网络适配器类型 MAC 地址MAC 地址格式MAC 地址类型MAC 地址发送顺序数据接收MAC 地址泄露问题 网络适配器 要将计算机连接到以太网&#xff0c;需要使用相应的网络适配器&#xff08;Adapter)&#xff0c;网络适配器一般简称为“网卡”。在计…

通信工程学习:什么是SRAM静态随机存取存储器

SRAM&#xff1a;静态随机存取存储器 SRAM&#xff0c;全称为Static Random-Access Memory&#xff0c;即静态随机存取存储器&#xff0c;是一种重要的随机存取存储器类型。以下是对SRAM的详细介绍&#xff1a; 一、定义与特点 定义&#xff1a; SRAM是一种只要保持通电&#…

CSS @规则(At-rules)系列详解___@import规则使用方法

CSS 规则(At-rules)系列详解 ___import规则使用方法 本文目录&#xff1a; 零、时光宝盒 一、import规则定义和用法 二、CSS import语法 2.1、语法格式 2.2、常见形式 2.3、语法说明 三、import使用方法例子 3.1、导入 CSS 规则 3.2、根据媒体查询条件导入 CSS 规则 …

结构体字节对齐的一些记录

‌结构体字节对齐的原因‌ 结构体字节对齐的主要原因是为了满足硬件平台的内存访问要求。某些硬件平台对特定类型的数据只能从特定的内存地址开始存取&#xff0c;如果数据没有进行对齐&#xff0c;可能会导致访问错误或效率低下。例如&#xff0c;某些架构的CPU在访问未对齐的…

原来CDC数据同步可以这么简单,零代码可视化一键数据同步

当前企业实时同步与分析场景中面临的挑战&#xff1a; 随着业务发展需要&#xff0c;实时分析成为企业目前的强需求&#xff0c;成为支撑企业业务发展的必须项。 一般来说&#xff0c;要满足数据实时分析的诉求&#xff0c;通常有两种方案&#xff1a; 第一种是直接使用源端…

多线程——解决线程安全问题

目录 前言 一、 synchronized 关键字 1. synchronized 的作用 1. synchronized 的特性 &#xff08;1&#xff09;互斥性 &#xff08;2&#xff09;可重入 2. synchronized 使用示例 &#xff08;1&#xff09;修饰代码块 &#xff08;2&#xff09;直接修饰普通方法…

Linux的GDB学习与入门

GDB GDB&#xff08;GNU Debugger&#xff09;是一个功能强大的调试工具&#xff0c;广泛用于调试 C、C 和其他编程语言编写的程序。它是 GNU 项目的一部分&#xff0c;专为帮助开发者在程序执行时检测和修复错误设计。GDB 能够控制程序的执行&#xff0c;查看程序内部的状态&…

2024诺奖引发思考,AI究竟是泡沫还是未来?

你好&#xff0c;我是三桥君 现在的AI技术发展得非常快&#xff0c;特别是深度学习和大模型这些技术&#xff0c;感觉和以前那些最后没搞成的技术泡沫不一样。 现在AI有超级强大的计算能力&#xff0c;还有大量的数据可以用来训练&#xff0c;算法也越来越厉害&#xff0c;能搞…

【单机游戏】【烛火地牢2:猫咪的诅咒】烛火地牢2:猫咪的诅咒介绍

《烛火地牢2&#xff1a;猫咪的诅咒》是一款将Roguelike与2D横版动作融为一体的独立游戏&#xff0c;由新西兰制作人Chris McFarland耗费3年时间精心制作。玩家将闯入不同的关卡接受挑战&#xff0c;通关要求是寻找每个关卡中的钥匙。在闯关时玩家能获得武器&#xff0c;防具&a…

关于int*的*号归属权问题

再根据函数指针定义&#xff1a;int (*int) (int a)。我们发现*和后面的标识符才是一体的 所以int *a,b;的写法更好&#xff0c;说明a是指针类型&#xff0c;b是int类型

让Kimi像人类思考的“Kimi探索版“已开启灰度内测!GPT-o1贡献者之一宣布离职|AI日报

文章推荐 “AI教父”辛顿与物理学家霍普菲尔德荣获诺贝尔物理学奖&#xff01;“AI教母”李飞飞选择谷歌云作为主要计算提供商&#xff5c;AI日报 今日热点 o1推理模型贡献者Luke Metz官宣从OpenAI离职 就在昨日&#xff0c;o1推理模型贡献者之一Luke Metz发文称自己经过两…

Ofcms-(java代码审计学习)

1、背景 根据《java代码审计实战》学习进行记录&#xff0c;java代码审计CMS实战。 2、Ofcms下载 可搜索Ofcms1.1.2版本进行下载。下载连接&#xff1a;ofcms: java 版CMS系统、基于java技术研发的内容管理系统、功能&#xff1a;栏目模板自定义、内容模型自定义、多个站点管…

五、UI弹窗提示

一、制作弹窗UI 二、创建脚本 1、继承WindowRoot&#xff08;UI基类&#xff09; 获取UI上面的组件 2、初始化 将这个文本失活 3、写一个提示出现的方法 这个派生类中&#xff0c;继承了基类的两个方法&#xff0c;设置显示和设置文本 对应基类的这两个方法 将动画赋值给动…

DDPM - Denoising Diffusion Probabilistic Models 扩散模型

DDPM - Denoising Diffusion Probabilistic Models 扩散模型 扩散模型概述 扩散模型是在模拟图像加噪的逆向过程。也就是在实现一个去噪的过程。简单的来说就包括两个过程组成 前向的扩散过程 Forward Diffusion Process反向扩散过程 Reverse Diffusion Process 下面我们对整个…