Javascript继承机制详解


Posted in Javascript onMay 30, 2017

学完了Javascript类和对象的创建之后,现在总结一下Javascript继承机制的实现。Javascript并不像Java那样对继承机制有严格明确的定义,它的实现方式正如它的变量的使用方式那样也是十分宽松的,你可以设计自己的方法“模仿”继承机制的实现。有以下几种方法:

1、对象冒充

<script type="text/javascript">
   function classA(str){
     this.str=str;
     this.printstr=function(){
       document.write(this.str);
       document.write("<br>");
     }
     this.getstr=function(){
       return this.str;
     }    
   }
   function classB(name,str){
     //下面这两句代码相当于将classA代码体中的内容搬到这里
     this.newMethod1=classA;
     this.newMethod1(str);
     //注意,这里的写法
     delete this.newMethod1;
     //新的方法和属性的定义须在删除了newMethod之后定义,因为可能覆盖超类的属性和方法。
     this.name=name;
     this.sayName=function(){
       document.write(this.name);
       document.write("<br>");
     }
     
   }
   var a=new classB("Amy","helloworld");
   a.printstr();
   alert(a.getstr());
   a.sayName();
 </script>

function定义的代码块就相当于一个类,你可以用而且它有this关键字,你可以用this为它添加属性和方法,上述代码中有以下两句:

this.newMethod1=classA;
 this.newMethod1(str);

classB中定义了newMethod1变量,它是一个引用,指向了classA,并且还调用了classA,这两句代码的作用等同于直接将classA代码块中的内容直接复制到这里,这样创建的classB对像当然具有classA的属性和方法了。对象冒充还可以实现多继承,如下:

function ClassZ() {
 this.newMethod = ClassX;
 this.newMethod();
 delete this.newMethod;

this.newMethod = ClassY;
 this.newMethod();
 delete this.newMethod;
}

不过,classY会覆盖classX中同名的属性和方法,如果设计没问题的话,classz也不应该继承具有相同属性和方法的不同类。

2、利用call()方法

<script type="text/javascript">
   function classA(str){
     this.str=str;
     this.printstr=function(){
       document.write(this.str);
       document.write("<br>");
     }
     this.getstr=function(){
       return this.str;
     }    
   }
   function classB(name,str){
   //利用call方法实现继承
     classA.call(this,str);
     this.name=name;
     this.sayName=function(){
       document.write(this.name);
       document.write("<br>");
     }
     
   }
   var a=new classB("Amy","helloworld");
   a.printstr();
   alert(a.getstr());
   a.sayName();
 </script>

call()方法中第一个参数传递一个对象,这里的this指的是当前对象,后面的参数(可能有多个)是指传递给调用call()方法的类(函数)所需要的参数,classA.call()也是相当于直接将classA代码块中的内容直接复制到这里,classB的对象同样可以直接使用classB中的变量和方法。

3、原型链

<script type="text/javascript">
   function cA(){};
   cA.prototype.name="John";
   cA.prototype.sayName=function(){
     document.write(this.name);
     document.write("<br>");
   }
   function cB(){};
   cB.prototype=new cA();
   cB.prototype.age=23;
   cB.prototype.sayAge=function(){
     document.write(this.age);
     document.write("<br>");
   }
   var objB=new cB();
   objB.sayAge();
   objB.sayName();
   document.write("is objB the instance of cA "+(objB instanceof cA));
   document.write("<br>");
   document.write("is objB the instance of cB "+(objB instanceof cB));
   document.write("<br>");
 </script>

这里对类的定义要用prototype关键字,定义function时不带有参数,prototype后面的变量或方法相当于java中被static修饰后的属性和方法,是属于所有对象的,这里有个特殊之处:cB.prototype=new cA();该句话相当于将cA对象内容复制给cB,cB还可以追加自己的属性和方法。

4、混合方法

<script type="text/javascript">
   function cA(name){
     this.name=name;
   };
   cA.prototype.sayName=function(){
     document.write(this.name);
     document.write("<br>");
   }
   function cB(name,age){
     cA.call(this,name);
     this.age=age;
   };
   cB.prototype=new cA();
   cB.prototype.sayAge=function(){
     document.write(this.age);
     document.write("<br>");
   }
   var objB=new cB("Alan",27);
   objB.sayName();
   objB.sayAge();
   document.write("is objB the instance of cA "+(objB instanceof cA));
   document.write("<br>");
   document.write("is objB the instance of cB "+(objB instanceof cB));
   document.write("<br>");
 </script>

这里可以将属性封装在类体内,而方法利用原型方式定义,个人感觉,这是一个很好的设计方法,利用prototype定义的函数可以为多个对象重用,这里需要注意两点:cB类体内有cA.call(this,name);同时还要将cB原型赋为cB对象,即:cB.prototype=new cA();cA.call(this,name)同样相当于将cA类块内的代码复制于此,后面一句话又将cA的方法添加给cB,同时cB还可以追加自己的属性和方法。

以上是本次对Javascript继承机制的总结,不足之处望各位指正批评。

Javascript 相关文章推荐
Extjs EditorGridPanel中ComboBox列的显示问题
Jul 04 Javascript
jQuery渐变发光导航菜单的实例代码
Mar 27 Javascript
JS 作用域与作用域链详解
Apr 07 Javascript
简介JavaScript中search()方法的使用
Jun 06 Javascript
解决jQuery使用JSONP时产生的错误
Dec 02 Javascript
Laravel中常见的错误与解决方法小结
Aug 30 Javascript
JavaScript实现图片本地预览功能【不用上传至服务器】
Sep 20 Javascript
10个经典的网页鼠标特效代码
Jan 09 Javascript
VUEJS 2.0 子组件访问/调用父组件的实例
Feb 10 Javascript
Vue 莹石摄像头直播视频实例代码
Aug 31 Javascript
vue 解决data中定义图片相对路径页面不显示的问题
Aug 13 Javascript
TypeScript中条件类型精读与实践记录
Oct 05 Javascript
Vue2.x中的Render函数详解
May 30 #Javascript
jQuery实现动态删除LI的方法
May 30 #jQuery
Vue.js实现在下拉列表区域外点击即可关闭下拉列表的功能(自定义下拉列表)
May 30 #Javascript
JS给按钮添加跳转功能类似a标签
May 30 #Javascript
jQuery异步提交表单实例
May 30 #jQuery
JS实现多级菜单中当前菜单不随页面跳转样式而发生变化
May 30 #Javascript
Angularjs中使用轮播图指令swiper
May 30 #Javascript
You might like
生成静态页面的PHP类
2006/07/15 PHP
php中多维数组按指定value排序的实现代码
2014/08/19 PHP
Ubuntu中启用php的mail()函数并解决发送邮件速度慢问题
2015/03/27 PHP
php实现自定义中奖项数和概率的抽奖函数示例
2017/05/26 PHP
jQuery表格行换色的三种实现方法
2011/06/27 Javascript
千分位数字格式化(用逗号隔开 代码已做了修改 支持0-9位逗号隔开)的JS代码
2013/12/05 Javascript
JS控制表格实现一条光线流动分割行的方法
2015/03/09 Javascript
jQuery插件Tmpl的简单使用方法
2015/04/27 Javascript
jQuery实现指定内容滚动同时左侧或其它地方不滚动的方法
2015/08/08 Javascript
详解jQuery Mobile自定义标签
2016/01/06 Javascript
Bootstrap轮播插件中图片变形的终极解决方案 使用jqthumb.js
2016/07/10 Javascript
浅谈js中的引用和复制(传值和传址)
2016/09/18 Javascript
从0开始学Vue
2016/10/27 Javascript
微信小程序全局变量改变监听的实现方法
2019/07/15 Javascript
vue在线动态切换主题色方案
2020/03/26 Javascript
[05:17]DOTA2誓师:今天我们在这里 明天TI4等我!
2014/03/26 DOTA
[04:40]DOTA2-DPC中国联赛1月26日Recap集锦
2021/03/11 DOTA
Python进程通信之匿名管道实例讲解
2015/04/11 Python
Python实现的概率分布运算操作示例
2017/08/14 Python
Python实现图片滑动式验证识别方法
2017/11/09 Python
Python实现使用卷积提取图片轮廓功能示例
2018/05/12 Python
python 2.7 检测一个网页是否能正常访问的方法
2018/12/26 Python
python爬取百度贴吧前1000页内容(requests库面向对象思想实现)
2019/08/10 Python
Python第三方包之DingDingBot钉钉机器人
2020/04/09 Python
python实现学生通讯录管理系统
2021/02/25 Python
巴西独家产品和现场演示购物网站:Shoptime
2019/07/11 全球购物
Java模拟试题
2014/11/10 面试题
毕业自荐信
2013/12/16 职场文书
推普周国旗下讲话稿
2014/09/21 职场文书
2014年学校体育工作总结
2014/12/08 职场文书
三峡人家导游词
2015/01/31 职场文书
2015年中秋节活动总结
2015/03/23 职场文书
导游词之南京汤山温泉
2019/11/26 职场文书
MySQL常见优化方案汇总
2022/01/18 MySQL
CSS font-variation 可变字体的魅力(实例详解)
2022/03/03 HTML / CSS
二维码条形码生成的JavaScript脚本库
2022/07/07 Javascript