js的子类继承父类

在很多时候我们写的js操作都有很多的公用的地方,每次都去复制过来,代码复用性很差,为何不像java一样,将公共的一些操作,属性提取出来作为父类,然后子类去继承并继续做加工,不影响父类。

下面我来介绍下js的类的三种继承的写法

拷贝继承:(通用型的 有new或无new的时候都可以)

  • 继承属性用父类的call方法

      父类.call(this,属性1,属性2,....);
    
  • 继承方法用for in

      extend(子类的原型,父类的原型);
      
      //for in 继承  jq也是这种 继承方法
      function extend(obj1, obj2){
        for(var attr in obj2){
              obj1[attr] = obj2[attr];
        }
      }        
    
  • 先看这个简单的例子,理解js的继承:

      <!DOCTYPE html>
      <html>
        <head>
          <meta charset="utf-8">
          <title>myTest</title>
        </head>
        <body>
          <script type="text/javascript">
            function CreatePerson(name,sex){
              this.name = name;
              this.sex = sex;
            }//父类构造器,定义父类的属性
            CreatePerson.prototype.showName = function(){
              alert(this.name);
            }//利用原型给写父类的方法属性
            var p1 = new CreatePerson('小明', 'boy');//实例化父类测试是否成功
            p1.showName();//小明
      
            //属性的继承采用的是调用父类的构造器的call
            function CreateStar(name, sex,job){
                CreatePerson.call(this,name,sex);
                this.job = job;
            }
      
            //将父类的原型给子类(更改一个都改变,这里相当于引用,而不是复制,这种是做不到继承的)
            // CreateStar.prototype=CreatePerson.prototype;
      
            extend(CreateStar.prototype,CreatePerson.prototype);
      
      //for in 继承  jq也是这种 继承方法
            function extend(obj1, obj2){
                for(var attr in obj2){
                  obj1[attr] = obj2[attr];
                }
            }
      
            var p2 = new CreateStar('xiaolki','girl','papa');
            p2.showName();
            p1.showName();
          </script>
        </body>
      </html>
    
  • 下面给出一段js拖动div的操作的继承

    1. 写父类对div1进行拖动的操作,及父类

       function Drag(id) {  //父类
           this.obj = document.getElementById(id);//获取所要拖动的dom节点
           this.disX = 0;
           this.disY = 0;
       }
       Drag.prototype.init = function () {
      
           var This = this;
      
           //鼠标按下事件初始化
           this.obj.onmousedown = function (ev) {
               var ev = ev || window.event;
               This.fnDown(ev);
               
               //鼠标移动事件初始化
               document.onmousemove = function (ev) {
                   var ev = ev || window.event;
                   This.fnMove(ev);
               };
               
               //鼠标松开事件初始化
               document.onmouseup = function () {
                   This.fnUp();
               };
               return false;
           };
      
       };
      
       //鼠标按下操作
       Drag.prototype.fnDown = function (ev) {
           this.disX = ev.clientX - this.obj.offsetLeft;
           this.disY = ev.clientY - this.obj.offsetTop;
       };
      
       //鼠标移动操作
       Drag.prototype.fnMove = function (ev) {
           this.obj.style.left = ev.clientX - this.disX + 'px';
           this.obj.style.top = ev.clientY - this.disY + 'px';
       };
      
       //鼠标松开操作
       Drag.prototype.fnUp = function () {
           document.onmousemove = null;
           document.onmouseup = null;
       };
      
  1. 子类继承父类

     function ChildDrag(id) {   //子类
         Drag.call(this, id);//继承父类的属性
     }
    
     //继承父类的方法
     extend(ChildDrag.prototype, Drag.prototype);
    
     //子类重写父类的鼠标移动方法
     ChildDrag.prototype.fnMove = function (ev) {
    
         var L = ev.clientX - this.disX;
         var T = ev.clientY - this.disY;
    
         if (L < 0) {
             L = 0;
         }
         else if (L > document.documentElement.clientWidth - this.obj.offsetWidth) {
             L = document.documentElement.clientWidth - this.obj.offsetWidth;
         }
    
         this.obj.style.left = L + 'px';
         this.obj.style.top = T + 'px';
     };
    
     //for in 来继承父类的方法
     function extend(obj1, obj2) {
         for (var attr in obj2) {
             obj1[attr] = obj2[attr];
         }
     }
    

类似继承: (new构造函数)

JS是没有类的概念的 , 把JS中的构造函数看做的类

要做属性和方法继承的时候,要分开继承

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<script>

function Aaa(){   //父类
    this.name = [1,2,3];
}

Aaa.prototype.showName = function(){
    alert( this.name );
};

function Bbb(){   //子类
    Aaa.call(this);
}

var F = function(){};
F.prototype = Aaa.prototype;//利用空方法只继承父类的方法,不继承属性
Bbb.prototype = new F();//将继承来的方法给子类引用
Bbb.prototype.constructor = Bbb; //因为是从父类引用而来,所以要重新修正指向问题

var b1 = new Bbb();
//b1.showName();
//alert( b1.name );
//alert( b1.constructor );
b1.name.push(4);

var b2 = new Bbb();

alert( b2.name );

</script>
</head>

<body>
</body>
</html>

原型继承:(无new对象)

<!DOCTYPE HTML>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>无标题文档</title>
    <script>

        var a = {
            name: '小明'
        };

        var b = cloneObj(a);

        b.name = '小强';

        //alert( b.name );
        alert(a.name);

        function cloneObj(obj) {

            var F = function () {
            };

            F.prototype = obj;

            return new F();

        }

    </script>
</head>

<body>
</body>
</html>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 8,072评论 2 17
  • 单例模式 适用场景:可能会在场景中使用到对象,但只有一个实例,加载时并不主动创建,需要时才创建 最常见的单例模式,...
    Obeing阅读 2,288评论 1 10
  • 如果不了解js的继承的写法,可以先去看看我之前写的js的子类继承父类文章http://www.jianshu.co...
    GQ1994阅读 2,530评论 0 3
  • 面向对象 类,原型,实例三者打交道 类里面存放的都是私有属性和方法 原型prototype上存的都是公有的属性和方...
    Dream_丹丹阅读 374评论 0 0
  • @转自GitHub 介绍js的基本数据类型。Undefined、Null、Boolean、Number、Strin...
    YT_Zou阅读 1,296评论 0 0

友情链接更多精彩内容