老生常谈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 UI Datepicker length为空或不是对象错误的解决方法
Dec 19 Javascript
js动态改变select选择变更option的index值示例
Jul 10 Javascript
jquery操作angularjs对象
Jun 26 Javascript
jQuery获取当前点击的对象元素(实现代码)
May 19 Javascript
基于JS代码实现当鼠标悬停表格上显示这一格的全部内容
Jun 12 Javascript
Vue.JS入门教程之处理表单
Dec 01 Javascript
微信小程序 this和that详解及简单实例
Feb 13 Javascript
浅析Angular19 自定义表单控件
Jan 31 Javascript
angular2中使用第三方js库的实例
Feb 26 Javascript
详解小程序毫秒级倒计时(适用于拼团秒杀功能)
May 05 Javascript
mpvue小程序循环动画开启暂停的实现方法
May 15 Javascript
vue分页插件的使用方法
Dec 25 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 危险函数解释 分析
2009/04/22 PHP
ThinkPHP中实例Model方法的区别说明
2010/08/21 PHP
PHP获取链表中倒数第K个节点的方法
2018/01/18 PHP
详解php与ethereum客户端交互
2018/04/28 PHP
PHP生成指定范围内的N个不重复的随机数
2019/03/18 PHP
PHP pthreads v3在centos7平台下的安装与配置操作方法
2020/02/21 PHP
js判断60秒以及倒计时示例代码
2014/01/24 Javascript
jQuery瀑布流插件Wookmark使用实例
2014/04/02 Javascript
wap图片滚动特效无css3元素纯js脚本编写
2014/08/22 Javascript
JavaScript编程中容易出BUG的几点小知识
2015/01/31 Javascript
jQuery实现渐变下拉菜单的简单方法
2015/03/11 Javascript
简要了解jQuery移动web开发的响应式布局设计
2015/12/04 Javascript
Bootstrap框架安装使用详解
2017/01/21 Javascript
js实现简单的手风琴效果
2017/02/27 Javascript
微信小程序 http请求的session管理
2017/06/07 Javascript
Node.js爬取豆瓣数据实例分析
2018/03/05 Javascript
Element-ui自定义table表头、修改列标题样式、添加tooltip、:render-header使用
2019/04/11 Javascript
聊聊鉴权那些事(推荐)
2019/08/22 Javascript
vue自定义组件实现双向绑定
2021/01/13 Vue.js
python中string模块各属性以及函数的用法介绍
2016/05/30 Python
python输入多行字符串的方法总结
2019/07/02 Python
Flask框架单例模式实现方法详解
2019/07/31 Python
使用TensorFlow-Slim进行图像分类的实现
2019/12/31 Python
python实现代码审查自动回复消息
2021/02/01 Python
详解html5页面 rem 布局适配方法
2018/01/12 HTML / CSS
澳大利亚波西米亚风情网上商店:Czarina
2019/03/18 全球购物
Bloomingdale’s阿联酋:选购奢华时尚、美容及更多
2020/09/22 全球购物
益模软件Java笔试题
2012/03/27 面试题
4s店机修工岗位职责
2013/12/20 职场文书
人民调解员先进事迹材料
2014/05/08 职场文书
机械专业毕业生自我鉴定2014
2014/10/04 职场文书
2014年中职班主任工作总结
2014/12/16 职场文书
2019年浪漫婚礼证婚词
2019/06/27 职场文书
如何使用 resize 实现图片切换预览功能
2021/08/23 HTML / CSS
Prometheus 监控MySQL使用grafana展示
2021/08/30 MySQL
Django框架之路由用法
2022/06/10 Python