老生常谈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 相关文章推荐
基于JQuery的简单实现折叠菜单代码
Sep 15 Javascript
javascript动态创建链接的方法
May 13 Javascript
js立即执行函数: (function ( ){})( ) 与 (function ( ){}( )) 有什么区别?
Nov 18 Javascript
jQuery实现form表单基于ajax无刷新提交方法详解
Dec 08 Javascript
深入剖析JavaScript中的函数currying柯里化
Apr 29 Javascript
JS实现显示带倒影的图片横排居中放大展示特效实例【测试可用】
Aug 23 Javascript
Ionic 2 实现列表滑动删除按钮的方法
Jan 22 Javascript
Vuex提升学习篇
Jan 11 Javascript
原生JS检测CSS3动画是否结束的方法详解
Jan 27 Javascript
微信小程序如何修改本地缓存key中单个数据的详解
Apr 26 Javascript
Node.js中console.log()输出彩色字体的方法示例
Dec 01 Javascript
Vue页面渲染中key的应用实例教程
Jan 12 Vue.js
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性能优化准备篇图解PEAR安装
2011/12/05 PHP
php自定义截取中文字符串-utf8版
2017/02/27 PHP
laravel实现按月或天或小时统计mysql数据的方法
2019/10/09 PHP
地址栏上的一段语句,改变页面的风格。(教程)
2008/04/02 Javascript
JavaScript 学习笔记(六)
2009/12/31 Javascript
用Javascript实现Sleep暂停功能代码
2010/09/03 Javascript
JS获取select-option-text_value的方法
2013/12/26 Javascript
Flow之一个新的Javascript静态类型检查器
2015/12/21 Javascript
JavaScript中对JSON对象的基本操作示例
2016/05/21 Javascript
浅谈JavaScript函数的四种存在形态
2016/06/08 Javascript
完全深入学习Bootstrap表单
2016/11/28 Javascript
深入理解Angularjs中的$resource服务
2016/12/31 Javascript
vue2 如何实现div contenteditable=“true”(类似于v-model)的效果
2017/02/08 Javascript
svg动画之动态描边效果
2017/02/22 Javascript
jQuery树插件zTree使用方法详解
2017/05/02 jQuery
Node.js 使用命令行工具检查更新
2017/06/08 Javascript
浅析Javascript中双等号(==)隐性转换机制
2017/10/27 Javascript
基于three.js编写的一个项目类示例代码
2018/01/05 Javascript
vue添加class样式实例讲解
2019/02/12 Javascript
LayUI数据接口返回实体封装的例子
2019/09/12 Javascript
Python查询Mysql时返回字典结构的代码
2012/06/18 Python
Python模块学习 datetime介绍
2012/08/27 Python
用Python中的字典来处理索引统计的方法
2015/05/05 Python
Python使用tablib生成excel文件的简单实现方法
2016/03/16 Python
利用Python实现在同一网络中的本地文件共享方法
2018/06/04 Python
Python元组常见操作示例
2019/02/19 Python
Python 安装第三方库 pip install 安装慢安装不上的解决办法
2019/06/18 Python
Python DES加密实现原理及实例解析
2020/07/17 Python
Html5移动端网页端适配(js+rem)
2021/02/03 HTML / CSS
会计电算一体化个人简历的自我评价
2013/10/15 职场文书
大学班级学风建设方案
2014/05/01 职场文书
校园活动策划方案
2014/06/13 职场文书
校本教研活动总结
2014/07/01 职场文书
2015国庆节放假通知范文
2015/07/30 职场文书
七夕情人节问候语
2015/11/11 职场文书
《司马光》教学反思
2016/02/22 职场文书