你的浏览器不支持canvas

做你害怕做的事情,然后你会发现,不过如此。

《智能社:JavaScript教程——从入门到精通》第26~29集笔记 面向对象

时间: 作者: 黄运鑫

本文章属原创文章,未经作者许可,禁止转载,复制,下载,以及用作商业用途。原作者保留所有解释权。


笔记目录

  1. 《智能社:JavaScript教程——从入门到精通》第1~5集笔记 事件
  2. 《智能社:JavaScript教程——从入门到精通》第6~10集笔记
  3. 《智能社:JavaScript教程——从入门到精通》第11~14集笔记 DOM操作和表格
  4. 《智能社:JavaScript教程——从入门到精通》第15~19集笔记 运动
  5. 《智能社:JavaScript教程——从入门到精通》第20~21集笔记 鼠标键盘事件
  6. 《智能社:JavaScript教程——从入门到精通》第22~23集笔记 事件高级应用
  7. 《智能社:JavaScript教程——从入门到精通》第24~25集笔记 Ajax
  8. 《智能社:JavaScript教程——从入门到精通》第26~29集笔记 面向对象
  9. 《智能社:JavaScript教程——从入门到精通》第30~31集笔记 坐标和cookie
  10. 《智能社:JavaScript教程——从入门到精通》第32集笔记 JS正则表达式
  • 本文为原创,转载请注明:https://blog.xinpapa.com/2017/12/19/zhinengshe26-29/

详细内容

1.JS中的面向对象

  • 面向对象编程(OOP)的特点
    • 抽象:抓住核心问题
    • 封装:不考虑内部实现,只考虑功能使用
    • 继承:从已有对象上,继承出新的对象
      • 多重继承
      • 多态
  • 对象的组成
    • 方法——函数:方法,就是属于一个对象的函数
    • 属性——变量:属性就是变量,只不过变量是自由的,属性是属于一个对象的

2.流行的面向对象编写方式

  • 用混合方式构造对象
    • 混合的构造函数/原型方式
    • Mixed Construstor Function/Prototype Method
  • 原则
    • 构造函数:加属性
    • 原型:加方法
    • 类名首字母大写
  • 代码如下:
    //创建一个构造函数
    function CreatePerson(name, qq) {
      this.name = name;
      this.qq = qq;
    };
    //用prototype原型添加方法
    CreatePerson.prototype.showName = function () {
      alert("姓名:" + this.name);
    };
    CreatePerson.prototype.showQQ = function () {
      alert("QQ:" + this.qq);
    };
    var obj = new CreatePerson("张三", "123");
    var obj2 = new CreatePerson("李四", "456");
    obj.showName();
    obj.showQQ();
    obj2.showName();
    obj2.showQQ();
    alert(obj.showName == obj2.showName);
    

3.实例:面向对象的选项卡

  • 把面向过程的程序,改写成面向对象的形式
    • 原则:
      • 不能有函数套函数,但可以有全局变量
    • 过程
      • onload→构造函数
      • 全局变量→属性
      • 函数→方法
    • 改错
      • this、事件、闭包、传参
    • 对象与闭包
      • 通过闭包传递this
  • 代码如下:
    #div1 input{background: white;}
    #div1 input.active{background: yellow;}
    #div1 div{
      width: 200px;
      height: 200px;
      background: #CCC;
      display: none;
    }
    
      <body>
          <div id="div1">
              <input class="active" type="button" value="aaa" />
              <input type="button" value="aaa" />
              <input type="button" value="aaa" />
              <div style="display: block;">11111</div>
              <div>22222</div>
              <div>33333</div>
          </div>
      </body>
    
    window.onload = function () {
      new TabSwitch("div1");
    };
    function TabSwitch(id) {
      var _this = this;
      var oDiv = document.getElementById(id);
      this.aBtn = oDiv.getElementsByTagName("input");
      this.aDiv = oDiv.getElementsByTagName("div");
      for (var i = 0; i < this.aBtn.length; i++) {
          this.aBtn[i].index = i;
          this.aBtn[i].onclick = function () {
              _this.fnClick(this);
          };
      }
    };
    TabSwitch.prototype.fnClick = function (oBtn) {
      for (var i = 0; i < this.aBtn.length; i++) {
          this.aBtn[i].className = "";
          this.aDiv[i].style.display = "none";
      }
      oBtn.className = "active";
      this.aDiv[oBtn.index].style.display = "block";
    };
    

4.Json方式的面向对象

  • 不适合多个对象
  • 把方法包在一个Json里

5.拖拽和继承

  • 面向对象的拖拽
    • 改写原有拖拽
    • 继承:在原有类的基础上略作修改,得到一个新的类,不影响原有类的功能
    • instanceof运算符:查看对象是否是某个类的实例
  • 代码如下:
    #div1{
      width: 200px;
      height: 200px;
      background: red;
      position: absolute;
    }
    #div2{
      width: 200px;
      height: 200px;
      background: goldenrod;
      position: absolute;
    }
    
      <body>
          <div id="div1">普通拖拽</div>
          <div id="div2">继承普通拖拽后加了推拽界限</div>
      </body>
    
    window.onload = function () {
      new Drag("div1");
      new LimitDrag("div2");
    };
    //定义一个拖拽类Drag,没有拖拽界限的普通拖拽
    function Drag(id) {
      var _this = this;
      this.disX = 0;
      this.disY = 0;
      this.oDiv = document.getElementById(id);
      this.oDiv.onmousedown = function (ev) {
          _this.fnDown(ev);
          return false;//解决拖拽时选中文字的bug
      };
    };
    Drag.prototype.fnDown = function (ev) {
      var _this = this;
      var oEvent = ev || event;
      this.disX = oEvent.clientX - this.oDiv.offsetLeft;
      this.disY = oEvent.clientY - this.oDiv.offsetTop;
      document.onmousemove = function (ev) {
          _this.fnMove(ev);
      };
      document.onmouseup = function (ev) {
          _this.fnUp();
      };
    };
    Drag.prototype.fnMove = function (ev) {
      var oEvent = ev || event;
      this.oDiv.style.left = oEvent.clientX - this.disX + "px";
      this.oDiv.style.top = oEvent.clientY - this.disY + "px";
    };
    Drag.prototype.fnUp = function () {
      document.onmousemove = null;
      document.onmouseup = null;
    };
    //定义一个LimitDrag类来继承Drag类
    function LimitDrag(id) {
      Drag.call(this, id);
    };
    //将Drag类的所有方法赋给LimitDrag类
    for (var i in Drag.prototype) {
      LimitDrag.prototype[i] = Drag.prototype[i];
    }
    //覆写父类的fnMove方法,增加拖拽界限
    LimitDrag.prototype.fnMove = function (ev) {
      var oEvent = ev || event;
      var l = oEvent.clientX - this.disX;
      var t = oEvent.clientY - this.disY;
      if (l < 0) {
          l = 0;
      } else if (l > document.documentElement.clientWidth - this.oDiv.offsetWidth) {
          l = document.documentElement.clientWidth - this.oDiv.offsetWidth;
      }
      if (t < 0) {
          t = 0;
      } else if (t > document.documentElement.clientHeight - this.oDiv.offsetHeight) {
          t = document.documentElement.clientHeight - this.oDiv.offsetHeight;
      }
      this.oDiv.style.left = l + "px";
      this.oDiv.style.top = t + "px";
    };
    

6.使用继承

  • 限制范围的拖拽类
    • 构造函数的伪装
      • 属性的继承
        • 原理:欺骗构造函数
      • call的使用:call可以改变函数执行时函数中的this
    • 原型链
      • 方法的继承
        • 原理:复制方法
      • 覆盖原型和方法复制

7.系统对象

  • 本地对象(非静态对象)
    • 必须new,才能用
    • 常用对象:ObjectFunctionArrayStringBooleanNumberDateRegExpError
  • 内置对象(静态对象)
    • 就是不用new,直接调用
      • GlobalMate
  • 宿主对象(由浏览器提供过的对象)
    • DOMBOM

对于本文内容有问题或建议的小伙伴,欢迎在文章底部留言交流讨论。