在js中,call,apply和prototype都可以实现对象的继承,下面我们看一个例子:

  function FatherObj1() {
this.sayhello = "I am join";
this.show = function () {
alert("I am FatherObj1");
};
this.getall = function () { if (arguments)
alert("GetAll:" + arguments[0]);
} }
function FatherObj2() {
this.sayhi = "I am Tom";
this.show = function () {
alert("I am FatherObj2");
}; }
function SonObj() {
this.sayby = "ByeBye";
this.show = function () {
alert("I am SonObj");
}; }

1.call&apply继承

我们先说一下 call和apply 的继承方式,

对于call和apply 在实现继承方面只是传参方式有区别,其他基本相同。

SonObj来继承FatherObj1:

function SonObj() {
this.sayby = "ByeBye";
this.show = function () {
alert("I am SonObj");
};
FatherObj1.call(this); //继承方式1
// FatherObj1.apply(this);//继承方式2 }

这里的 FatherObj1.call(this); 可以理解为把FatherObj1这个对象里的属性和方法委托给this也就是Sonobj,或者遗传给Sonobj,这种方式与C#,Java的继承不同的是:js可以继承多个父类,而C#,java只能继承一个,

那么问题来了,js继承多个父类,而多个父类如果有同名方法或者同名属性,会发生什么事情?

  function SonObj() {
this.sayby = "ByeBye";
this.show = function () {
alert("I am SonObj");
};
FatherObj1.call(this); //继承方式1
FatherObj2.call(this); }

上面代码我让SonObj同时继承FatherObj1和FatherObj2,大家可以看到,在子类和父类对象里都存在同名方法show,

 var son = new SonObj();
son.show();

运行之后的结果是:I am FatherObj2,这个结果说明 FatherObj2的show方法把SonObj的同名方法给重写了,下面我调整一下SonObj里面的方法顺序,

 function SonObj() {
this.sayby = "ByeBye"; FatherObj1.call(this); //继承方式1
FatherObj2.call(this);
this.show = function () {
alert("I am SonObj");
}; }

输出结果:I am SonObj,可见js对同名方法的处理是,执行过程中,后者替代前者,不受子父类的约束,

如果我只想继承FatherObj1的getall方法,不想继承整个类怎么做呢?我们可以这样:

  function SonObj() {
this.sayby = "ByeBye"; this.show = function () {
alert("I am SonObj");
};
}
var son = new SonObj();
var fa = new FatherObj1();
fa.getall.call(son, 1, 2);
fa.getall.apply(son, [1, 2]);

从call和apply 的调用上看,细心的同学应该发现了其中的不同,call的参数是 call(obj,arg1,arg2),而apply的参数是一个对象加一个数组,apply(obj,[arg1,arg2])

我现在给FatherObj2加一个原型方法:

  FatherObj2.prototype.StaticForYou = function () {
alert("FatherObj2_StaticForYou"); };

现在我用SonObj去继承这个方法的话,可以这样写:

 FatherObj2.prototype.StaticForYou.call(SonObj.prototype);

或者:

 FatherObj2.prototype.StaticForYou.call(SonObj);

同样,用apply也可以实现,只是很相同,就不写了。

2 Prototype的继承:

  SonObj.prototype = new FatherObj1();
var son = new SonObj();

这样,son就有了fatherobj1的所有方法,

同样,我们用son来调用show方法

  son.show();

输出结果是:I am SonObj,而不是父类的方法返回结果,是的,prototype的继承其实就是复制父类的方法和属性,如果自己有同名方法或属性,就不去复制,而保留本身的属性或方法。

那如果我想要调用父类的同名方法怎么做呢?可以把上面代码改成

        var father = new FatherObj1();
father.show.call(son);

这样相当于又回到了call和apply的继承问题。

现在我们想,既然用call和apply 可以继承多个父类,那我们同理用prototype来试试:

 SonObj.prototype = new FatherObj1();
SonObj.prototype = new FatherObj2();

这样sonobj会不会继承这两个父类的属性和方法呢?

结果我们发现,已经调用不到FatherObj1的方法了,只能调用到FatherObj2的方法和属性。下面的父类把上面的父类替换掉了。

 SonObj.prototype.StaticForYou = function () {
alert("Static_Come");
}
son.StaticForYou();

输出结果:Static_Come,如果想输出父类的原型方法呢?推一下就出来啦

 FatherObj2.prototype.StaticForYou.call(SonObj);

js继承之call,apply和prototype随谈的更多相关文章

  1. js中继承的几种用法总结(apply,call,prototype)

    一,js中对象继承 js中有三种继承方式 1.js原型(prototype)实现继承 <SPAN style="BACKGROUND-COLOR: #ffffff">& ...

  2. js中继承的方法总结(apply,call,prototype)

    一,js中对象继承 js中有三种继承方式 1.js原型(prototype)实现继承 代码如下: <SPAN style="<SPAN style="FONT-SIZE ...

  3. js继承相关

    这几天看到一篇文章详解Javascript的继承实现,发现js还是很深奥的,比如call.apply.prototype这些,问起来我也能说的头头是道的,但是看到一些复杂的代码有的时候还是会迷糊,所以 ...

  4. JS 继承总结

    ES里面没有真正的继承,但是能通过某些手段达到继承效果,从而让一个类拥有另外一个类的方法  类 =>构造函数 继承描述某语言环境---魔兽世界 哈!其实我没玩过  魔兽世界里面 有Humen类  ...

  5. js继承

    js继承有5种实现方式: 继承第一种方式:对象冒充 function Parent(username){ this.username = username; this.hello = function ...

  6. js继承关系

    跟传统面向对象语言比起来,js在继承关系方面比较特别,如果第一次看恐怕会有些抓狂,偶就是这样(又透露小白本质#=_=),从哪里说起好呢?函数调用? js中函数的调用方式大致可分以下几种: 1. 普通函 ...

  7. 老生常谈--Js继承小结

    一直以来,对Js的继承有所认识,但是认识不全面,没什么深刻印象.于是,经常性的浪费很多时间重新看博文学习继承,今天工作不是特别忙,有幸看到了http://www.slideshare.net/stoy ...

  8. Js继承小结

    Js继承小结 一直以来,对Js的继承有所认识,但是认识不全面,没什么深刻印象.于是,经常性的浪费很多时间重新看博文学习继承,今天工作不是特别忙,有幸看到了http://www.slideshare.n ...

  9. js继承之借用构造函数继承

    我的上一篇文章介绍了,原型链继承模式.但是单纯的原型链模式并不能很好地实现继承. 一.原型链的缺点 1.1 单纯的原型链继承最大的一个缺点,来自于原型中包含引用类型的值. 本来,我们没有通过原型链实现 ...

随机推荐

  1. Python strip函数用法小结

    声明:s为字符串,rm为要删除的字符序列 s.strip(rm)        删除s字符串中开头.结尾处,位于 rm删除序列的字符 s.lstrip(rm)       删除s字符串中开头处,位于 ...

  2. ETL的数据来源,处理,保存

    1.ETL 数据来源:HDFS 处理方式:Mapreduce 数据保存:HBase 2.为什么保存在Hbase中 数据字段格式不唯一/不相同/不固定,采用hbase的动态列的功能非常适合 因为我们的分 ...

  3. Windows上搭建Kafka运行环境

    完整解决方案请参考: Setting Up and Running Apache Kafka on Windows OS   在环境搭建过程中遇到两个问题,在这里先列出来,以方便查询: 1. \Jav ...

  4. 大商创 sql追踪 卖家入驻

    ' ' ' ', '', '', '') ' Query ' Query ' Query ' Query ' Query ' Query ' Query ' Query ' Query ' Query ...

  5. 使用百度编辑器时,报错:从客户端("...)中检测到有潜在危险的 Request.Form 值

    ajax请求失败,提交不上去 起初没找到报错的这句话,可能由于我用了其他第三方插件的原因,后来改动了一下,出现了这个错误 然后百度得到答案:http://www.cnblogs.com/tearer/ ...

  6. ASP.NET 5

    docs.asp.net installing on windows Choosing the Right .NET For You on the Server DotNetCore: DotNetC ...

  7. 亚马逊如何变成 SOA(面向服务的架构)?

    阮一峰 日期: 2016年9月10日 上一篇文章,我摘录了<程序员的呐喊>.这本书有趣的内容太多,今天再摘录一段. 1. 亚马逊公司不仅是世界最大的网络书店,还是世界最大的云服务商.它是怎 ...

  8. oracle数据库安装

    1.oracle10g下载完成后,选择“setup.exe”启动安装. 2.oracle主目录位置就是oracle准备安装的位置,称为"Oracle_Home".Oracle安装的 ...

  9. CSS 在IE6, IE7 和IE8中的差别////////////////z

    CSS 在IE6, IE7 和IE8中的差别 关于浏览器的最离奇的统计结果之一就是Internet Explorer 版本6,7和8共存.截至本文,Internet Explorer各个版本总共占据了 ...

  10. 17. 星际争霸之php设计模式--职责链模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...