老生常谈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 相关文章推荐
解析URI与URL之间的区别与联系
Nov 22 Javascript
获取select元素被选中的文本内容的js代码
Jan 29 Javascript
jquery map方法使用示例
Apr 23 Javascript
JQuery组件基于Bootstrap的DropDownList(完整版)
Jul 05 Javascript
BootStrap日期控件在模态框中选择时间下拉菜单无效的原因及解决办法(火狐下不能点击)
Aug 18 Javascript
jQuery组件easyui基本布局实现代码
Aug 25 Javascript
bootstrap flask登录页面编写实例
Nov 01 Javascript
把json格式的字符串转换成javascript对象或数组的方法总结
Nov 03 Javascript
Vue键盘事件用法总结
Apr 18 Javascript
layui点击按钮页面会自动刷新的解决方案
Oct 25 Javascript
elementui更改el-dialog关闭按钮的图标d的示例代码
Aug 04 Javascript
在vue中使用vant TreeSelect分类选择组件操作
Nov 02 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
利用递归把多维数组转为一维数组的函数
2006/10/09 PHP
php学习笔记 PHP面向对象的程序设计
2011/06/13 PHP
jQuery EasyUI API 中文文档 - DateBox日期框
2011/10/15 PHP
JQuery FlexiGrid的asp.net完美解决方案 dotNetFlexGrid-.Net原生的异步表格控件
2010/09/12 Javascript
JavaScript 高级篇之函数 (四)
2012/04/07 Javascript
jQuery实现查找最近父节点的方法
2016/06/23 Javascript
理解javascript中的Function.prototype.bind的方法
2017/02/03 Javascript
Javascript实现运算符重载详解
2018/04/07 Javascript
angular2路由之routerLinkActive指令【推荐】
2018/05/30 Javascript
JS实现同一DOM元素上onClick事件与onDblClick事件并存的解决方法
2018/06/07 Javascript
javascript实现超好看的3D烟花特效
2020/01/01 Javascript
Vue 解决路由过渡动画抖动问题(实例详解)
2020/01/05 Javascript
vue如何使用rem适配
2021/02/06 Vue.js
详解Python中with语句的用法
2015/04/15 Python
浅谈python中的变量默认是什么类型
2016/09/11 Python
Python之Scrapy爬虫框架安装及使用详解
2017/11/16 Python
python交互式图形编程实例(三)
2017/11/17 Python
详解Python字符串切片
2019/05/20 Python
python画图——实现在图上标注上具体数值的方法
2019/07/08 Python
python实现的接收邮件功能示例【基于网易POP3服务器】
2019/09/11 Python
python使用yield压平嵌套字典的超简单方法
2019/11/02 Python
Python-Flask:动态创建表的示例详解
2019/11/22 Python
基于Python和PyYAML读取yaml配置文件数据
2020/01/13 Python
Html5实现iPhone开机界面示例代码
2013/06/30 HTML / CSS
波比布朗英国官网:Bobbi Brown英国
2017/11/13 全球购物
什么是servlet链?
2014/07/13 面试题
财务部出纳岗位职责
2013/12/22 职场文书
仓管员岗位责任制
2014/02/19 职场文书
《蒙娜丽莎之约》教学反思
2014/02/27 职场文书
建筑结构施工求职信
2014/07/11 职场文书
2015年机关后勤工作总结
2015/05/26 职场文书
2016教师读书思廉心得体会
2016/01/23 职场文书
python geopandas读取、创建shapefile文件的方法
2021/06/29 Python
Python中22个万用公式的小结
2021/07/21 Python
详解Vue slot插槽
2021/11/20 Vue.js
SpringBoot使用AOP实现统计全局接口访问次数详解
2022/06/16 Java/Android