老生常谈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 学习之旅 (3)
Feb 05 Javascript
jQuery ctrl+Enter shift+Enter实现代码
Feb 07 Javascript
JavaScript去掉空格的方法集合
Dec 28 Javascript
Extjs4 GridPanel 的几种样式使用介绍
Apr 18 Javascript
javascript实现连续赋值
Aug 10 Javascript
Vue.JS入门教程之事件监听
Dec 01 Javascript
jQuery Json数据格式排版高亮插件json-viewer.js使用方法详解
Jun 12 jQuery
vue-router2.0 组件之间传参及获取动态参数的方法
Nov 10 Javascript
Vue使用vue-area-linkage实现地址三级联动效果的示例
Jun 27 Javascript
利用Angular2的Observables实现交互控制的方法
Dec 27 Javascript
axios封装,使用拦截器统一处理接口,超详细的教程(推荐)
May 02 Javascript
redux.js详解及基本使用
May 24 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提取数据库内容中的图片地址并循环输出
2010/03/21 PHP
Symfony2函数用法实例分析
2016/03/18 PHP
PHP编写简单的App接口
2016/08/28 PHP
用javascript实现在小方框中浏览大图的代码
2007/08/14 Javascript
JS 遮照层实现代码
2010/03/31 Javascript
Javscript调用iframe框架页面中函数的方法
2014/11/01 Javascript
js对象继承之原型链继承实例
2015/01/10 Javascript
jquery validate和jquery form 插件组合实现验证表单后AJAX提交
2015/08/26 Javascript
Node.js实现文件上传
2016/07/05 Javascript
jQuery实现的简单拖拽功能示例
2016/09/13 Javascript
ES6入门教程之let和const命令详解
2017/05/17 Javascript
微信分享调用jssdk实例
2017/06/08 Javascript
jquery+css实现下拉列表功能
2017/09/03 jQuery
js 显示日期时间的实例(时间过一秒加1)
2017/10/25 Javascript
vue父组件向子组件动态传值的两种方法
2017/11/11 Javascript
用ES6写全屏滚动插件的示例代码
2018/05/02 Javascript
Vue 中如何正确引入第三方模块的方法步骤
2019/05/05 Javascript
JS实现点击下拉列表文本框中出现对应的网址,点击跳转按钮实现跳转
2019/11/25 Javascript
Java实现的执行python脚本工具类示例【使用jython.jar】
2018/03/29 Python
python环境路径配置以及命令行运行脚本
2019/04/02 Python
python使用协程实现并发操作的方法详解
2019/12/27 Python
jupyter notebook tensorflow打印device信息实例
2020/04/20 Python
使用Python FastAPI构建Web服务的实现
2020/06/08 Python
Keras官方中文文档:性能评估Metrices详解
2020/06/15 Python
Python docutils文档编译过程方法解析
2020/06/23 Python
通过代码实例了解Python异常本质
2020/09/16 Python
Gucci法国官方网站:意大利奢侈品牌
2018/07/25 全球购物
开业庆典答谢词
2014/01/18 职场文书
给校长的建议书
2014/03/12 职场文书
2014年文学毕业生自我鉴定
2014/04/23 职场文书
学校与家长安全责任书
2014/07/23 职场文书
秋冬农业生产标语
2014/10/09 职场文书
2015年党员自我剖析材料
2014/12/17 职场文书
确保减税降费落地生根,用实实在在措施
2019/07/19 职场文书
MySQL串行化隔离级别(间隙锁实现)
2022/06/16 MySQL
修改Nginx配置返回指定content-type的方法
2022/09/23 Servers