深入面向对象
编程思想
-  面向过程:多个步骤=> 解决问题 性能较高,适合跟硬件联系很紧密的东西,如单片机 但代码维护成本高,扩展性差 
-  面向对象:问题所需功能分解为一个一个的对象(分工合作)=> 接口 明确分工,灵活,代码可复用,容易维护和开发,适合大型软件项目 但性能较低 
[!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);
综合案例
通过面向对象的方法实现提示框的功能
同个提示框的功能可以给其他按钮复用,只需更改参数
- 一个构造函数创建一个标签,多样化通过实参进行传入
- 在原型对象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>

![[Hbase]一 HBase基础](https://i-blog.csdnimg.cn/direct/854d61c7a6f449febcaf5fac2c048e0f.png)

![[Javase]封装、继承、多态与异常处理](https://i-blog.csdnimg.cn/direct/758ed6a1e77b49389eeb898ba26d5be3.png)















