zoukankan      html  css  js  c++  java
  • js中的继承

      JS虽然不像是JAVA那种强类型的语言,但也有着与JAVA类型的继承属性,那么JS中的继承是如何实现的呢?

    一、构造函数继承

     1 在构造函数中,同样属于两个新创建的函数,也是不相等的
     2 
     3     function Fn(name){
     4         this.name = name;
     5         this.show = function(){
     6             alert(this.name);
     7         }
     8     }
     9     var obj1 = new Fn("AAA");
    10     var obj2 = new Fn("BBB");
    11     console.log(obj1.show==obj2.show);        //false
    12     
    13     此时可以看出构造函数的多次创建会产生多个相同函数,造成冗余太多。
    14     
    15     利用原型prototype解决。首先观察prototype是什么东西
    16     function Fn(){}
    17     console.log(Fn.prototype);
    18     //constructor表示当前的函数属于谁
    19     //__proto__  ==  [[prototype]],书面用语,表示原型指针
    20  
    21     var fn1 = new Fn();
    22     var fn2 = new Fn();
    23     Fn.prototype.show = function(){
    24         alert(1);
    25     }
    26     console.log(fn1.show==fn2.show);     //ture
    27     
    28     此时,任何一个对象的原型上都有了show方法,由此得出,构造函数Fn.prototype身上的添加的方法,相当于添加到了所有的Fn身上。

    二、call和applay继承

     1 function Father(skill){
     2         this.skill = skill;
     3         this.show = function(){
     4             alert("我会"+this.skill);
     5         }
     6     }
     7     var father = new Father("绝世木匠");
     8     function Son(abc){
     9         //这里的this指向函数Son的实例化对象
    10         //将Father里面的this改变成指向Son的实例化对象,当相遇将father里面所有的属性和方法都复制到了son身上
    11         //Father.call(this,abc);//继承结束,call适合固定参数的继承
    12         //Father.apply(this,arguments);//继承结束,apply适合不定参数的继承
    13     }
    14     father.show()
    15     var son = new Son("一般木匠");
    16     son.show();

    三、原型链继承(demo)

      这个的么实现一个一个简单的拖拽,a->b的一个继承。把a的功能继承给b。

    HTML:
    1
    <div id="drag1"></div> 2 <div id="drag2"></div>
    CSS:
    1
    *{margin: 0;padding: 0;} 2 #drag1{ 100px;height: 100px;background: red;position: absolute;} 3 #drag2{ 100px;height: 100px;background: black;position: absolute;left: 500px;}
     JS: 
    1
    function Drag(){} 2 Drag.prototype={ 3 constructor:Drag, 4 init:function(id){ 5 this.ele=document.getElementById(id); 6 this.cliW=document.documentElement.clientWidth||document.body.clientWidth; 7 this.cliH=document.documentElement.clientHeight||document.body.clientHeight; 8 var that=this; 9 this.ele.onmousedown=function(e){ 10 var e=event||window.event; 11 that.disX=e.offsetX; 12 that.disY=e.offsetY; 13 document.onmousemove=function(e){ 14 var e=event||window.event; 15 that.move(e); 16 } 17 that.ele.onmouseup=function(){ 18 document.onmousemove=null; 19 } 20 } 21 }, 22 move:function(e){ 23 this.x=e.clientX-this.disX; 24 this.y=e.clientY-this.disY; 25 this.x=this.x<0?this.x=0:this.x; 26 this.y=this.y<0?this.y=0:this.y; 27 this.x=this.x>this.cliW-this.ele.offsetWidth?this.x=this.cliW-this.ele.offsetWidth:this.x; 28 this.y=this.y>this.cliH-this.ele.offsetHeight?this.y=this.cliH-this.ele.offsetHeight:this.y; 29 this.ele.style.left=this.x+'px'; 30 this.ele.style.top=this.y+'px'; 31 } 32 } 33 new Drag().init('drag1') 34 function ChidrenDrag(){} 35 ChidrenDrag.prototype=new Drag() 36 new ChidrenDrag().init('drag2')

    四、混合继承

     1 function Father(skill,id){
     2         this.skill = skill;
     3         this.id = id;
     4     }
     5     Father.prototype.show = function(){
     6         alert("我是father,这是我的技能"+this.skill);
     7     }
     8 
     9     function Son(){
    10         Father.apply(this,arguments);
    11     }
    12     //如果不做son的原型即成father的原型,此时会报错:son.show is not a function
    13     Son.prototype = Father.prototype;
    14     //因为,如果不让son的原型等于father的原型,son使用apply是继承不到原型上的方法
    15     //但这是一种错误的原型继承示例,如果使用这种方式,会导致修改son原型上的show方法时,会把father身上的show也修改
    16     //内存的堆和栈机制
    17     Son.prototype.show = function(){
    18         alert("我是son,这是我的技能"+this.skill);
    19     }
    20     var father = new Father("专家级铁匠","father");
    21     var son = new Son("熟练级铁匠","son");
    22     father.show();
    23     son.show();
    24 
    25     上面的示例应该修改成以下形式:
    26     以上红色的代码应改成:
    27     for(var i in Father.prototype){
    28         Son.prototype[i] = Father.prototype[i];
    29     }
    30     //遍历father的原型身上的所有方法,依次拷贝给son的原型,这种方式称为深拷贝
    31 
    32     这种继承方式叫做混合继承,用到了for-in继承,cell和apple继承。

    五、Es6的class继承(demo)

      这个demo的功能和原型链继承的demo功能一样,a->b的继承

    HTML:
    1 <div id="drag1"></div>
    2 <div id="drag2"></div>
    CSS:
    1 *{margin: 0;padding: 0;}
    2 #drag1{ 100px;height: 100px;background: red;position: absolute;}
    3 #drag2{ 100px;height: 100px;background: black;position: absolute;left: 500px;}
     JS:
    1
    class Drag{ 2 constructor(id){ 3 this.ele=document.getElementById(id); 4 this.init(); 5 }; 6 init(){ 7 var that=this; 8 this.ele.onmousedown=function(e){ 9 var e=event||window.event; 10 that.disX=e.offsetX; 11 that.disY=e.offsetY; 12 document.onmousemove=function(e){ 13 var e=event||window.event; 14 that.move(e); 15 } 16 that.ele.onmouseup=function(){ 17 document.onmousemove=null; 18 that.ele.onmouseup=null; 19 } 20 } 21 }; 22 move(e){ 23 this.ele.style.left=e.clientX-this.disX+"px"; 24 this.ele.style.top=e.clientY-this.disY+"px"; 25 } 26 } 27 28 new Drag("drag1"); 29 30 class ExtendsDrag extends Drag{ 31 constructor(id){ 32 super(id); 33 } 34 } 35 36 new ExtendsDrag("drag2")

      我总结的这几种继承方法.两个demo继承的方法大家最好在编译器上跑一下,看看。这样才能更深刻的去理解。尤其是原型链的继承,js作为一个面向对象的编程语言,还是很常用的。

      

  • 相关阅读:
    .net中实现运行时从字符串动态创建对象
    C# 用 VB.net 函數庫 實現全角與半角轉換
    實現.net 加載插件方式
    VS2008下載
    Lotus Notes Send EMail from VB or VBA
    用C#写vs插件中的一些Tip
    SQL2005中异常处理消息框可直接使用
    C#路径/文件/目录/I/O常见操作汇总
    利用.net反射动态调用指定程序集的中的方法
    说说今年的计划
  • 原文地址:https://www.cnblogs.com/alongup/p/9271397.html
Copyright © 2011-2022 走看看