老生常谈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 相关文章推荐
IE6与IE7中,innerHTML获取param的区别
Mar 15 Javascript
select、radio表单回显功能实现避免使用jquery载入赋值
Jun 08 Javascript
javascript垃圾收集机制与内存泄漏详细解析
Nov 11 Javascript
JS实现网页Div层Clone拖拽效果
Sep 26 Javascript
简单实现js选项卡切换效果
Feb 03 Javascript
jquery实现垂直和水平菜单导航栏
Aug 27 Javascript
AngularJS+Bootstrap实现多文件上传与管理
Nov 08 Javascript
基于ExtJs在页面上window再调用Window的事件处理方法
Jul 26 Javascript
基于Vue2的独立构建与运行时构建的差别(详解)
Dec 06 Javascript
vue实现类似淘宝商品评价页面星级评价及上传多张图片功能
Oct 29 Javascript
基于vue实现圆形菜单栏组件
Jul 05 Javascript
vue项目中使用particles实现粒子背景效果及遇到的坑(按钮没有点击响应)
Feb 11 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
虫族 Zerg 魔法科技
2020/03/14 星际争霸
php定义数组和使用示例(php数组的定义方法)
2014/03/29 PHP
php实现统计目录文件大小的函数
2015/12/25 PHP
Javascript和Ajax中文乱码吐血版解决方案
2009/12/21 Javascript
让ie运行js时提示允许阻止内容运行的解决方法
2010/10/24 Javascript
善用事件代理,警惕闭包的性能陷阱。
2011/01/20 Javascript
html向js方法传递参数具体实现
2013/08/08 Javascript
jquery固定底网站底部菜单效果
2013/08/13 Javascript
JavaScript的继承的封装介绍
2013/10/15 Javascript
jqplot通过ajax动态画折线图的方法及思路
2013/12/08 Javascript
动态的9*9乘法表效果的实现代码
2016/05/16 Javascript
AngularJS中的API(接口)简单实现
2016/07/28 Javascript
详解vue-cli开发环境跨域问题解决方案
2017/06/06 Javascript
原生js二级联动效果
2017/06/20 Javascript
vue-router 路由基础的详解
2017/10/17 Javascript
JS实现图片放大镜插件详解
2017/11/06 Javascript
Vue.js获取被选择的option的value和text值方法
2018/08/24 Javascript
详解webpack-dev-server使用方法
2018/09/14 Javascript
基于Vue 实现一个中规中矩loading组件
2019/04/03 Javascript
JQuery实现ul中添加LI和删除指定的Li元素功能完整示例
2019/10/16 jQuery
如何解决vue在ios微信&quot;复制链接&quot;功能问题
2020/03/26 Javascript
微信小程序获取当前时间及星期几的实例代码
2020/09/20 Javascript
pycharm 使用心得(八)如何调用另一文件中的函数
2014/06/06 Python
讲解Python中的递归函数
2015/04/27 Python
Python中的os.path路径模块中的操作方法总结
2016/07/07 Python
python中类变量与成员变量的使用注意点总结
2017/04/29 Python
python机器学习案例教程——K最近邻算法的实现
2017/12/28 Python
使用Python+Splinter自动刷新抢12306火车票
2018/01/03 Python
pandas分区间,算频率的实例
2019/07/04 Python
pymysql 插入数据 转义处理方式
2020/03/02 Python
python自动下载图片的方法示例
2020/03/25 Python
使用Filters滤镜弥补CSS3的跨浏览器问题以及兼容低版本IE
2013/01/23 HTML / CSS
建筑工程技术专业求职信
2014/07/16 职场文书
教师学习党的群众路线教育实践活动心得体会
2014/10/31 职场文书
Pytorch数据读取之Dataset和DataLoader知识总结
2021/05/23 Python
python常见的占位符总结及用法
2021/07/02 Python