JS 组合继承

204 阅读4分钟

组合继承

借用父构造函数只能实现继承属性

利用原型链继承只能实现继承方法

可以将两个组合一起就形成可以继承属性与方法

// 组合继承 = 借用构造函数继承 + 原型链继承 继承了父构造函数的属性与方法 
// 借用构造函数继承 继承 父构造函数的属性
// 原型链继承 继承 父构造函数的方法
function Father(uname, age) {
  this.uname = uname
  this.age = age
}
Father.prototype.sayHello = function () {
  console.log('hello')
}
​
function Son(uname, age) {
  // 使用借用构造函数实现继承属性
  Father.call(this, uname, age)
}
​
Son.prototype = new Father()
// 让 构造函数的原型对象的 constructor 指回 Son 构造函数
Son.prototype.constructor = Son// 实例化 Son 构造函数
const s1 = new Son('吴所谓', 18)
console.log(s1)
​
s1.sayHello()

原型链

什么是原型链

概念

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

原型链研究的是 对象属性的 查找机制。

理解起来,并不是太难。

  • 实例对象 有原型对象
  • 原型对象也是对象,那也有原型对象..............
  • 这样就形成了多层继承了

原型链的作用:

  1. 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
  2. 如果没有就查找它的原型(也就是 proto指向的 prototype 原型对象)
  3. 如果还没有就查找原型对象的原型(Object的原型对象)
  4. 依此类推一直找到 Object 为止(null)
  5. proto对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线

instanceof运算符

构造函数的 prototype 属性是否出现在某个实例对象的原型链上?

可以通过instanceof运算符来检测

基本语法

对象 instanceof 构造函数

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

消息提示对象封装需求分析

目标

练习面向对象写插件(模态框)

需求

  1. 定义模态框 Modal 构造函数,用来创建对象
  2. 模态框具备 打开功能 open 方法 (按钮点击可以打开模态框)
  3. 模态框 具备关闭功能 close 方法

open 和 close 方法 写到哪里?

构造函数的原型对象上,共享方法

所以可以分为三个模块, 构造函数, open方法, close方法

基本代码结构

<!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>
​
  </script>
</body></html>

消息提示对象封装-Modal 构造函数

目标

能够写出 Modal构造函数

步骤

  • 需要的公共属性:  标题(title)、提示信息内容(message)  可以设置默认参数

  • 在页面中创建模态框

    1. 创建div标签可以命名为:modalBox
    2. div标签的类名为 modal
    3. 标签内部添加 基本结构,并填入相关数据

示例代码

<!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 构造函数 生成 模态框
    function Modal(title, message) {
      this.title = title
      this.message = message
      // 1.1 创建 div的盒子 document.createElement('div')
      this.modal = document.createElement('div')
      // 1.2 添加类名
      this.modal.classList.add('modal')
      // 1.3 给 this.modal 添加内容
      this.modal.innerHTML = `
        <div class="header">${this.title} <i>x</i></div>
        <div class="body">${this.message}</div>
      `
    }
​
  </script>
</body></html>

消息提示对象封装-open方法

目标

能够写出open方法

步骤

  • 写到构造函数的原型对象身上
  • 把刚才创建的modalBox 添加到 页面 body 标签中
  • open 打开的本质就是 把创建标签添加到页面中
  • 点击按钮, 实例化对象,传入对应的参数,并执行 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 构造函数 生成 模态框
    function Modal(title, message) {
      this.title = title
      this.message = message
      // 1.1 创建 div的盒子 document.createElement('div')
      this.modal = document.createElement('div')
      // 1.2 添加类名
      this.modal.classList.add('modal')
      // 1.3 给 this.modal 添加内容
      this.modal.innerHTML = `
        <div class="header">${this.title} <i>x</i></div>
        <div class="body">${this.message}</div>
      `
    }
​
    // 3. 给 Modal 原型对象身上添加 open 的方法
    Modal.prototype.open = function() {
      // 将 this.modal 追加到 body 标签里面 
      document.body.appendChild(this.modal)
    }
​
    // 2. 给 删除 按钮注册点击事件 
    document.querySelector('#delete').addEventListener('click', function () {
      const m = new Modal('温馨提示', '您没有删除权限操作')
      // console.log(m)
      m.open()
    })
​
    // 2. 给 删除 按钮注册点击事件 
    document.querySelector('#login').addEventListener('click', function () {
      const m = new Modal('友情提示', '您没有注册账号')
      m.open()
    })
​
​
  </script>
</body></html>

消息提示对象封装-close方法

目标

能够写出close方法

步骤

  • 写到构造函数的原型对象身上
  • 把刚才创建的modalBox 从页面 body 标签中 删除
  • 需要注意,x 删除按钮绑定事件,要写到open里面添加
  • 因为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 构造函数 生成 模态框
    function Modal(title, message) {
      this.title = title
      this.message = message
      // 1.1 创建 div的盒子 document.createElement('div')
      this.modal = document.createElement('div')
      // 1.2 添加类名
      this.modal.classList.add('modal')
      // 1.3 给 this.modal 添加内容
      this.modal.innerHTML = `
        <div class="header">${this.title} <i>x</i></div>
        <div class="body">${this.message}</div>
      `
    }
​
    // 3. 给 Modal 原型对象身上添加 open 的方法
    Modal.prototype.open = function () {
      // 如果当前的页面上已经有了 model 的 dom元素 就不追加 没有才追加
      if (!document.querySelector('.modal')) {
        // 将 this.modal 追加到 body 标签里面 
        document.body.appendChild(this.modal)
        // 找到 i 标签 注册点击事件
        // document.querySelector('.modal i').addEventListener('click', function () {
        //   console.log(this)
        // })
        document.querySelector('.modal i').addEventListener('click', () => this.close())
      }
    }
​
    // 4. 给 Modal 原型对象 身上 添加 close 的方法 该方法的作用就是将 创建的 modal 盒子移除即可
    Modal.prototype.close = function () {
      // 自己.remove() | 父dom对象.removeChild(要删除的子元素)
      document.querySelector('.modal').remove()
    }
​
    // 2. 给 删除 按钮注册点击事件 
    document.querySelector('#delete').addEventListener('click', function () {
      const m = new Modal('温馨提示', '您没有删除权限操作')
      // console.log(m)
      m.open()
    })
​
    // 2. 给 删除 按钮注册点击事件 
    document.querySelector('#login').addEventListener('click', function () {
      const m = new Modal('友情提示', '您没有注册账号')
      m.open()
    })
​
​
  </script>
</body></html>