js继承之call,apply和prototype随谈
在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随谈的更多相关文章
- js中继承的几种用法总结(apply,call,prototype)
一,js中对象继承 js中有三种继承方式 1.js原型(prototype)实现继承 <SPAN style="BACKGROUND-COLOR: #ffffff">& ...
- js中继承的方法总结(apply,call,prototype)
一,js中对象继承 js中有三种继承方式 1.js原型(prototype)实现继承 代码如下: <SPAN style="<SPAN style="FONT-SIZE ...
- js继承相关
这几天看到一篇文章详解Javascript的继承实现,发现js还是很深奥的,比如call.apply.prototype这些,问起来我也能说的头头是道的,但是看到一些复杂的代码有的时候还是会迷糊,所以 ...
- JS 继承总结
ES里面没有真正的继承,但是能通过某些手段达到继承效果,从而让一个类拥有另外一个类的方法 类 =>构造函数 继承描述某语言环境---魔兽世界 哈!其实我没玩过 魔兽世界里面 有Humen类 ...
- js继承
js继承有5种实现方式: 继承第一种方式:对象冒充 function Parent(username){ this.username = username; this.hello = function ...
- js继承关系
跟传统面向对象语言比起来,js在继承关系方面比较特别,如果第一次看恐怕会有些抓狂,偶就是这样(又透露小白本质#=_=),从哪里说起好呢?函数调用? js中函数的调用方式大致可分以下几种: 1. 普通函 ...
- 老生常谈--Js继承小结
一直以来,对Js的继承有所认识,但是认识不全面,没什么深刻印象.于是,经常性的浪费很多时间重新看博文学习继承,今天工作不是特别忙,有幸看到了http://www.slideshare.net/stoy ...
- Js继承小结
Js继承小结 一直以来,对Js的继承有所认识,但是认识不全面,没什么深刻印象.于是,经常性的浪费很多时间重新看博文学习继承,今天工作不是特别忙,有幸看到了http://www.slideshare.n ...
- js继承之借用构造函数继承
我的上一篇文章介绍了,原型链继承模式.但是单纯的原型链模式并不能很好地实现继承. 一.原型链的缺点 1.1 单纯的原型链继承最大的一个缺点,来自于原型中包含引用类型的值. 本来,我们没有通过原型链实现 ...
随机推荐
- RHEL/CentOS/Fedora各种源(EPEL、Remi、RPMForge、RPMFusion)配置
最新文章:Virson’s Blog CentOS默认自带CentOS-Base.repo源,但官方源中去除了很多有版权争议的软件,而且安装的软件也不是最新的稳定版.Fedora自带的源中也找不到很多 ...
- Gradle--ubuntu
在Ubuntu安装Gradle也是很简单.切记请勿使用apt-get安装Gradle.因为Ubuntu源的Gradle实在太旧.我用的搜狐的源,竟然是2011年. 下面是安装步骤: 1.在官网下载最新 ...
- List<T> 添加 DataTable
public System.Data.DataTable getDataTable() { System.Data.DataTable dt = new System.Data.DataTable() ...
- sshpass 用法举例
关于sshpass 背景 在Linux后台中,经常会用到ssh.scp等命令.需要进行认证,手动输入密码,是交互式的过程. 当将ssh.scp等命令做成自动化脚本时,可能需要非交互式的登录过程,此时可 ...
- openstack搭建配置
安装和配置网络节点vim /etc/sysctl.confnet.ipv4.ip_forward=1net.ipv4.conf.all.rp_filter=0net.ipv4.conf.default ...
- Android内存泄露
Android 内存泄漏是一个十分头疼的事情.LeakCanary是一款开源软件,主要作用是检测 Android APP 内存泄露.比起以前的 MAT 工具,LeakCanary 有着十分强大的功能, ...
- Java基础之扩展GUI——使用字体对话框(Sketcher 5 displaying a font dialog)
控制台程序. 为了可以选择系统支持的字体,我们定义了一个FontDialog类: // Class to define a dialog to choose a font import java.aw ...
- asp.net mvc4 System.Web.Optimization找不到引用
在MVC4的开发中,如果创建的项目为空MVC项目,那么在App_Start目录下没有BundleConfig.cs项的内容,在手动添加时在整个库中都找不到:System.Web.Optimizatio ...
- paper 110:凸优化和非凸优化
数学中最优化问题的一般表述是求取,使,其中是n维向量,是的可行域,是上的实值函数.凸优化问题是指是闭合的凸集且是上的凸函数的最优化问题,这两个条件任一不满足则该问题即为非凸的最优化问题. 其中,是 凸 ...
- Thinking in UML-1-为什么需要UML
1 从面向过程到面向对象 面向过程认为我们的世界是由一个个相互关联的小系统组成.逻辑严密.环环相扣.井然有序.但是我们这个世界从来不是一成不变的.世界的复杂性和频繁变革不是面向过程可以轻易应付应付的. ...