老生常谈JS中的继承及实现代码


Posted in Javascript onJuly 06, 2018

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

一、构造函数继承

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

二、call和applay继承

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

三、原型链继承(demo)

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

HTML:

<div id="drag1"></div>
 <div id="drag2"></div>

CSS:

*{margin: 0;padding: 0;}
 #drag1{width: 100px;height: 100px;background: red;position: absolute;}
 #drag2{width: 100px;height: 100px;background: black;position: absolute;left: 500px;}

 JS:  

function Drag(){}
  Drag.prototype={
   constructor:Drag,
   init:function(id){
    this.ele=document.getElementById(id);
    this.cliW=document.documentElement.clientWidth||document.body.clientWidth;
    this.cliH=document.documentElement.clientHeight||document.body.clientHeight;
    var that=this;
    this.ele.onmousedown=function(e){
     var e=event||window.event;
     that.disX=e.offsetX;
     that.disY=e.offsetY;
     document.onmousemove=function(e){
      var e=event||window.event;
      that.move(e);
     }
     that.ele.onmouseup=function(){
      document.onmousemove=null;
     }
    }  
   },
   move:function(e){
    this.x=e.clientX-this.disX;
    this.y=e.clientY-this.disY;
    this.x=this.x<0?this.x=0:this.x;
    this.y=this.y<0?this.y=0:this.y;
    this.x=this.x>this.cliW-this.ele.offsetWidth?this.x=this.cliW-this.ele.offsetWidth:this.x;
    this.y=this.y>this.cliH-this.ele.offsetHeight?this.y=this.cliH-this.ele.offsetHeight:this.y;
    this.ele.style.left=this.x+'px';
    this.ele.style.top=this.y+'px';
   }
  }
  new Drag().init('drag1')
  function ChidrenDrag(){}
  ChidrenDrag.prototype=new Drag()
  new ChidrenDrag().init('drag2')

四、混合继承

function Father(skill,id){
  this.skill = skill;
  this.id = id;
 }
 Father.prototype.show = function(){
  alert("我是father,这是我的技能"+this.skill);
 }
 function Son(){
  Father.apply(this,arguments);
 }
 //如果不做son的原型即成father的原型,此时会报错:son.show is not a function
 Son.prototype = Father.prototype;
 //因为,如果不让son的原型等于father的原型,son使用apply是继承不到原型上的方法
 //但这是一种错误的原型继承示例,如果使用这种方式,会导致修改son原型上的show方法时,会把father身上的show也修改
 //内存的堆和栈机制
 Son.prototype.show = function(){
  alert("我是son,这是我的技能"+this.skill);
 }
 var father = new Father("专家级铁匠","father");
 var son = new Son("熟练级铁匠","son");
 father.show();
 son.show();
 上面的示例应该修改成以下形式:
 以上红色的代码应改成:
 for(var i in Father.prototype){
  Son.prototype[i] = Father.prototype[i];
 }
 //遍历father的原型身上的所有方法,依次拷贝给son的原型,这种方式称为深拷贝
 这种继承方式叫做混合继承,用到了for-in继承,cell和apple继承。

五、Es6的class继承(demo)

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

HTML:

<div id="drag1"></div>
 <div id="drag2"></div>

CSS:

*{margin: 0;padding: 0;}
 #drag1{width: 100px;height: 100px;background: red;position: absolute;}
 #drag2{width: 100px;height: 100px;background: black;position: absolute;left: 500px;}

 JS:

class Drag{
   constructor(id){
    this.ele=document.getElementById(id);
    this.init();
   };
   init(){
    var that=this;
    this.ele.onmousedown=function(e){
     var e=event||window.event;
     that.disX=e.offsetX;
     that.disY=e.offsetY;
     document.onmousemove=function(e){
      var e=event||window.event;
      that.move(e);
     }
     that.ele.onmouseup=function(){
      document.onmousemove=null;
      that.ele.onmouseup=null;
     }
    }
   };
   move(e){
    this.ele.style.left=e.clientX-this.disX+"px";
    this.ele.style.top=e.clientY-this.disY+"px";
   }
  }
  new Drag("drag1");
  class ExtendsDrag extends Drag{
   constructor(id){
    super(id);
   }
  }
  new ExtendsDrag("drag2")

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

总结

以上所述是小编给大家介绍的JS中的继承及实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
Javascript操作select方法大全[新增、修改、删除、选中、清空、判断存在等]
Sep 26 Javascript
JavaScript闭包 懂不懂由你反正我是懂了
Oct 21 Javascript
JavaScript函数的4种调用方法详解
Apr 22 Javascript
jQuery 删除或是清空某个HTML元素示例
Aug 04 Javascript
[原创]推荐10款最热门jQuery UI框架
Aug 19 Javascript
jQuery使用之处理页面元素用法实例
Jan 19 Javascript
JavaScript跨平台的开源框架NativeScript
Mar 24 Javascript
javascript高级编程之函数表达式 递归和闭包函数
Nov 29 Javascript
jQuery插件HighCharts绘制2D柱状图、折线图的组合双轴图效果示例【附demo源码下载】
Mar 09 Javascript
利用vue.js插入dom节点的方法
Mar 15 Javascript
在vue中使用jsx语法的使用方法
Sep 30 Javascript
JS pushlet XMLAdapter适配器用法案例解析
Oct 16 Javascript
vue.js使用v-if实现显示与隐藏功能示例
Jul 06 #Javascript
vue.js计算属性computed用法实例分析
Jul 06 #Javascript
vue.js实现的绑定class操作示例
Jul 06 #Javascript
vue.js实现插入数值与表达式的方法分析
Jul 06 #Javascript
详解浏览器缓存和webpack缓存配置
Jul 06 #Javascript
JS获取子节点、父节点和兄弟节点的方法实例总结
Jul 06 #Javascript
深入浅析AngularJs模版与v-bind
Jul 06 #Javascript
You might like
PHP 5.3新增魔术方法__invoke概述
2014/07/23 PHP
php检测图片主要颜色的方法
2015/07/01 PHP
ThinkPHP框架中使用Memcached缓存数据的方法
2018/03/31 PHP
PHP格式化显示时间date()函数代码
2018/10/03 PHP
PHP $O00OO0=urldecode &amp; eval 解密,记一次商业源码的去后门
2020/09/13 PHP
javascript multibox 全选
2009/03/22 Javascript
实现动画效果核心方式的js代码
2013/09/27 Javascript
JavaScript中使用ActiveXObject操作本地文件夹的方法
2014/03/28 Javascript
C#中使用迭代器处理等待任务
2015/07/13 Javascript
javascript cookie的简单应用
2016/02/24 Javascript
原生js和css实现图片轮播效果
2017/02/07 Javascript
JavaScript实现的选择排序算法实例分析
2017/04/14 Javascript
vue.js父组件使用外部对象的方法示例
2017/04/25 Javascript
详解使用 Node.js 开发简单的脚手架工具
2018/06/08 Javascript
javascript实现简单打字游戏
2019/10/29 Javascript
你不知道的 TypeScript 高级类型(小结)
2020/08/28 Javascript
[05:07]DOTA2英雄梦之声_第14期_暗影恶魔
2014/06/20 DOTA
[09:43]DOTA2每周TOP10 精彩击杀集锦vol.5
2014/06/25 DOTA
python如何使用unittest测试接口
2018/04/04 Python
使用Python实现在Windows下安装Django
2018/10/17 Python
超简单的Python HTTP服务
2019/07/22 Python
Pytorch 计算误判率,计算准确率,计算召回率的例子
2020/01/18 Python
Python生成pdf目录书签的实例方法
2020/10/29 Python
Python利用matplotlib绘制折线图的新手教程
2020/11/05 Python
Aveda美国官网:天然护发产品、洗发水、护发素和沙龙
2016/12/09 全球购物
美国著名手表网站:Timepiece
2017/11/15 全球购物
Lookfantastic希腊官网:英国知名美妆购物网站
2018/09/15 全球购物
英国鞋网:Rubber Sole
2020/03/03 全球购物
客服实习的个人自我鉴定
2013/10/20 职场文书
计算机专业职业生涯规划范文
2014/01/19 职场文书
社区矫正工作方案
2014/06/04 职场文书
村委会贫困证明范本
2014/09/17 职场文书
教师群众路线教育实践活动学习笔记
2014/11/05 职场文书
有关信念的名言语录集锦
2019/12/06 职场文书
python 中yaml文件用法大全
2021/07/04 Python
解决Springboot PostMapping无法获取数据的问题
2022/05/06 Java/Android