ES6之class和继承的几种

class类

    // class 关键字表明 类的生命  注意:javascript没有 class 
    // class 的作用 :面向对象编程的工具
    // 这个语法糖,语义化更好,编程的复杂度也有降低;

    // 1、构造函数
    // 2、原型对象
    function Factory() {
      this.a = "我是factory里面的一条数据"
    }
    Factory.prototype.init = function () {
      console.log("这是一个功能")
    }
    var fac = new Factory()
    fac.init()


    // class 包含了两个部分
    // 1、构造函数
    // 2、原型方法
    class Factory {
      // 构造函数变成了统一的名称 : constructor
      constructor() {
        this.a = "这是一条数据"
      }
      init() {
        console.log("这是一个功能")
      }
    }
    // 调用 class调用 和 构造函数+原型的调用 一样
    var fac = new Factory()
    fac.init()

拖拽案例

<!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>
    #box1,
    #box2 {
      width: 100px;
      height: 100px;
      background: skyblue;
      position: absolute;
      left: 0;
      top: 0;
    }

    #box2 {
      background: springgreen;
      left: 200px;
    }
  </style>
</head>

<body>
  <div id="box1"></div>
  <div id="box2"></div>
  <script>
    class Drag {
      constructor(selector) {
        // 选择拖拽的元素
        this.ele = document.querySelector(selector)
        // 调用事件
        this.bindEvent()
      }
      bindEvent() {
        let self = this
        // 鼠标按下事件
        self.ele.onmousedown = function (evt) {
          let e = evt || window.event
          // es6的解构赋值 
          let { offsetX: x, offsetY: y } = e
          document.onmousemove = function (evt) {
            let e = evt || window.event
            // 鼠标的移动时坐标
            // 为了让元素跟着鼠标点击的位置而不是跟着鼠标的 client 走
            self.eleMove(e.clientX - x, e.clientY - y)
          }
        }
        // 当鼠标抬起事件
        document.onmouseup = function () {
          // 清除鼠标移动事件
          document.onmousemove = null
        }
      }
      // 移动坐标
      eleMove(x, y) {
        this.ele.style.left = x + "px"
        this.ele.style.top = y + "px"
      }
    }
    var drag1 = new Drag("#box1")
    var drag2 = new Drag("#box2")

  </script>
</body>

</html>

继承

1、es5继承

    // 继承 : 
    // 1. 构造函数里的方法,属性拿过来;
    // 2. 原型对象里的方法拿过来;

    // 继承 构造数里面功能和调用;

    // 其实构造函数就是加工实例对象的工厂=> 给实例对象添加属性。 
    // javascript里面提供的构造函数继承方式灵感来自代工;

    function Father() {
      this.a = "hello world";
      this.b = "你好世界";
    }
    // new Father();
    // 1. 创建Father类的实例对象;
    // 2. 给Father类创建的 实例对象 上面添加属性 a 和 属性 b;
    function Son() {
      // 方便查看去个别名,实际上没有用;
      var son_ins = this;
      // 狸猫换太子 用call指向;      
      Father.call(son_ins);
    }
    var son = new Son();
    console.log(son)
    // 1. 创建 Son 的实例对象;
    // 2. 把Son的实例放在Father的构造函数里加工;


    // 【 带有参数的继承 】;
    function Father(a, b) {
      this.a = a;
      this.b = b;
    }
    function Son(son_a, son_b) {
      // 方便查看去个别名,实际上没有用;
      var son_ins = this;
      // 狸猫换太子;    
      // call形式的参数传递;
      // Father.call(son_ins , son_a , son_b );
      // apply形式的参数传递;  因为使用了 arguments 所以可以省略形参;
      // arguments => [ son_a , son_b ]
      Father.apply(son_ins, arguments)
    }
    var son = new Son("hello world", "你好世界");


    // 【 原型继承 】 
    //  1. for in 继承; ( 浅克隆继承 )
    //  2. 原型链继承;
    function Father() { };
    Father.prototype.init = function () {
      console.log("hello world")
    }
    function Son() { }
    // 克隆人家地址;
    for (var attr in Father.prototype) {
      // 给 Son 的原型写入 Father 的地址;
      Son.prototype[attr] = Father.prototype[attr];
    }
    var son = new Son();
    // console.log(son);
    son.init();

在这里插入图片描述

原型继承 1、原型链继承

<!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>
    // 上头有人;
    function Father() {
    }
    Father.prototype.init = function () {
      console.log("这是father里面的功能")
    }
    Father.prototype.show = function () {
      console.log("这是father里面的功能")
    }
    function Son() { }

    // 因为 father 的实例对象有指针指向 Father.prototype 那么此时可以把
    //  son原型里面的原型指针替换成 指向fahter原型对象的原型指针;

    // 我们可以直接把Son 的原型对象替换成 Father 的实例对象;
    Son.prototype = new Father();
    Son.prototype.show = function () {
      console.log("这是son里面的功能")
    }

    // 原型继承的方法,不要在构造函数里面写东西;
    var son = new Son();
    console.log(son) 
    
    son.init();
    // 在子类原型对象上 new 父类的构造函数即可完成原型继承;
    son.show();
    // 因为Son的原型对象方法show距离更近,所以我们会优先访问到 Son 原型上的show方法;
    // 就近原则

  </script>
</body>

</html>

在这里插入图片描述

原型继承 2、for in 继承,浅克隆继承 (拖拽案例)

<!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>
    #box,
    #box2 {
      width: 100px;
      height: 100px;
      background: skyblue;
      position: absolute;
      left: 0;
      top: 0;
    }

    #box2 {
      background: springgreen;
      left: 200px;
    }
  </style>
</head>

<body>
  <div id="box"></div>
  <div id="box2"></div>

  <script>
 function Drag(selector) {
      // 拖拽的元素;
      this.ele = document.querySelector(selector);
      this.bindEvent();
    }
    // tip : 方法分割是没有逗号的;
    Drag.prototype.bindEvent = function () {
      var self = this;
      self.ele.onmousedown = function (evt) {
        // 拖拽开启;
        // console.log("拖拽开启");
        let e = evt || event;
        // 获取 offsetX 和 offsetY;
        let { offsetX: x, offsetY: y } = e;
        document.onmousemove = function (evt) {
          let e = evt || event;
          // 拖拽进行中;
          // console.log("拖拽进行中");
          // 为了让元素跟着鼠标点击的位置走而不是跟着鼠标的client 走;
          self.eleMove(e.clientX - x, e.clientY - y);
        }
      }
      this.ele.onmouseup = function () {
        // console.log("拖拽结束");
        document.onmousemove = null;
      }
    }

    Drag.prototype.eleMove = function (x, y) {
      this.ele.style.left = x + "px";
      this.ele.style.top = y + "px";
    }

    function BoundaryDrag(selector) {
      var son_ins = this;
      Drag.call(son_ins, selector);
    }

    for (var attr in Drag.prototype) {
      BoundaryDrag.prototype[attr] = Drag.prototype[attr];
    }
    // 使用的时候注意下 : 如果在构造函数里面有方法的调用,那么请把调用放在继承之后。
    BoundaryDrag.prototype.eleMove = function (x, y) {
      x = x < 0 ? 0 : x;
      this.ele.style.left = x + "px";
      this.ele.style.top = y + "px";
    }
    var drag = new BoundaryDrag("#box");
   </script>
</body>

</html>

2、es6继承(拖拽案例)

ES6 继承方式 : extends 关键字; 表示类的整体继承

<!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>
    #box1,
    #box2 {
      width: 100px;
      height: 100px;
      background: skyblue;
      position: absolute;
      left: 0;
      top: 0;
    }

    #box2 {
      background: springgreen;
      left: 200px;
    }
  </style>
</head>

<body>
  <div id="box1"></div>
  <div id="box2"></div>

  <script>
    class Drag {
      constructor(selector) {
        // 拖拽的元素;
        this.ele = document.querySelector(selector);
        this.bindEvent();
      }
      // tip : 方法分割是没有逗号的;
      bindEvent() {
        let self = this;
        self.ele.onmousedown = function (evt) {
          // 拖拽开启;
          // console.log("拖拽开启");
          let e = evt || event;
          // 获取 offsetX 和 offsetY;
          let { offsetX: x, offsetY: y } = e;
          document.onmousemove = function (evt) {
            let e = evt || event;
            // 拖拽进行中;
            // console.log("拖拽进行中");
            // 为了让元素跟着鼠标点击的位置走而不是跟着鼠标的client 走;
            self.eleMove(e.clientX - x, e.clientY - y);
          }
        }
        document.onmouseup = function () {
          // console.log("拖拽结束");
          document.onmousemove = null;
        }
      }
      eleMove(x, y) {
        this.ele.style.left = x + "px";
        this.ele.style.top = y + "px";
      }
    }

    // ES6 继承方式 :  extends 关键字; 表示类的整体继承;
    // 有边界的拖拽; 
    class BoundaryDrag extends Drag {
      // 继承之后更改分成两种 : 
      // 1. 构造函数里面的更改;
      // 2. 原型对象上方法的更改;
      constructor(selector) {
        // 拖拽的元素;
        // super相当于父级类的构造函数;
        super(selector);
        // 编写自己的代码;
        console.log("带有边界检测的拖拽");
      }

      // 构造函数继承 : 
      // 1. 调用super; tip : 如果原本父类有参数,那必须传入参数;
      // 2. 加入自己更新的代码;

      // 1、在原型对象上方法的更改,更多的是使用覆盖的模式进行更改;
      eleMove(x, y) {
        x = x < 0 ? 0 : x;
        this.ele.style.left = x + "px";
        this.ele.style.top = y + "px";
      }

      // 2、注意以下 内部更新代码; 并不是适用于所有的开发场景;
      eleMove(x, y) {
        // 添加边界检测功能;
        x = x < 0 ? 0 : x;
        // 表示调用父类的eleMove 原型方法;
        super.eleMove(x, y);
      }
    }
    let drg1 = new BoundaryDrag("#box1");
    let drg2 = new BoundaryDrag("#box2");

  </script>
</body>

</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值