Javascript 面向对象编程2:构造函数的继承
这个系列的第一部分,主要介绍了如何"封装"数据和方法,以及如何从原型对象生成实例。
对象之间的"继承"的五种方法。
比如,现在有一个"动物"对象的构造函数。
function Animal(){
this.species="动物";
}
还有一个“猫"对象的构造函数。
function Cat(name,color){
this.name=name;
this.color=color;
}
那怎么才能让”猫“继承”动物“呢?
一、 构造函数绑定
第一种方法也是最简单的方法,使用call或apply方法,将父对象的构造函数绑定在子对象上,即在子对象构造函数中加一行:
function Cat(name,color){
Animal.apply(this, arguments);
this.name = name;
this.color = color;
}
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物
二、 prototype模式
第二种方法更常见,使用prototype属性。
如果"猫"的prototype对象,指向一个Animal的实例,那么所有"猫"的实例,就能继承Animal了。
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物
三、 直接继承prototype
第三种方法是对第二种方法的改进。由于Animal对象中,不变的属性都可以直接写入Animal.prototype。所以,我们也可以让Cat()跳过 Animal(),直接继承Animal.prototype。
现在,我们先将Animal对象改写:
function Animal(){ }
Animal.prototype.species = "动物";
然后,将Cat的prototype对象,然后指向Animal的prototype对象,这样就完成了继承。
Cat.prototype = Animal.prototype;
Cat.prototype.constructor = Cat;
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物
与前一种方法相比,这样做的优点是效率比较高(不用执行和建立Animal的实例了),比较省内存。缺点是 Cat.prototype和Animal.prototype现在指向了同一个对象,那么任何对Cat.prototype的修改,都会反映到Animal.prototype。
所以,上面这一段代码其实是有问题的。请看第二行
Cat.prototype.constructor = Cat;
这一句实际上把Animal.prototype对象的constructor属性也改掉了!
alert(Animal.prototype.constructor); // Cat
四、 利用空对象作为中介
由于"直接继承prototype"存在上述的缺点,所以就有第四种方法,利用一个空对象作为中介。
var F = function(){};
F.prototype = Animal.prototype;
Cat.prototype = new F();
Cat.prototype.constructor = Cat;
F是空对象,所以几乎不占内存。这时,修改Cat的prototype对象,就不会影响到Animal的prototype对象。
alert(Animal.prototype.constructor); // Animal
我们将上面的方法,封装成一个函数,便于使用。
function extend(Child, Parent) {
var F = function(){};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype;
}
使用的时候,方法如下
extend(Cat,Animal);
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物
五、 拷贝继承
简单说,如果把父对象的所有属性和方法,拷贝进子对象,也能够实现继承。
首先,还是把Animal的所有不变属性,都放到它的prototype对象上。
function Animal(){}
Animal.prototype.species = "动物";
然后,再写一个函数,实现属性拷贝的目的。
function extend2(Child, Parent) {
var p = Parent.prototype;
var c = Child.prototype;
for (var i in p) {
c[i] = p[i];
}
c.uber = p;
}
这个函数的作用,就是将父对象的prototype对象中的属性,一一拷贝给Child对象的prototype对象。
使用的时候,这样写:
extend2(Cat, Animal);
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物
Javascript 面向对象编程2:构造函数的继承的更多相关文章
- (二)Javascript面向对象编程:构造函数的继承
Javascript面向对象编程:构造函数的继承 这个系列的第一部分,主要介绍了如何"封装"数据和方法,以及如何从原型对象生成实例. 今天要介绍的是,对象之间的"继承 ...
- Javascript面向对象编程:构造函数的继承
今天要介绍的是,对象之间的"继承"的五种方法. 比如,现在有一个"动物"对象的构造函数. function Animal(){ this.species = & ...
- javascript面向对象(二):构造函数的继承
本文来自阮一峰 这个系列的第一部分,主要介绍了如何"封装"数据和方法,以及如何从原型对象生成实例. 今天要介绍的是,对象之间的"继承"的五种方法. 比如,现在有 ...
- javascript面向对象(三):非构造函数的继承
本文来自阮一峰 这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现"继承". 今天是最后一个部分,介绍不使用构造函数实现"继承" ...
- JavaScript面向对象编程学习笔记
1 Javascript 面向对象编程 所谓"构造函数",其实就是一个普通函数,但是内部使用了this变量.对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例 ...
- (三)Javascript面向对象编程:非构造函数的继承
Javascript面向对象编程:非构造函数的继承 这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现"继承". 今天是最后一个部分,介绍不使 ...
- Javascript面向对象编程(三):非构造函数的继承(对象的深拷贝与浅拷贝)
Javascript面向对象编程(三):非构造函数的继承 作者: 阮一峰 日期: 2010年5月24日 这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现&quo ...
- Javascript面向对象编程(二):构造函数的继承 作者:yuan一峰
Javascript面向对象编程(二):构造函数的继承 作者: 阮一峰 日期: 2010年5月23日 这个系列的第一部分,主要介绍了如何"封装"数据和方法,以及如何从原型对象生 ...
- JavaScript 面向对象编程(三):非构造函数对象的继承
JavaScript 面向对象编程(三):非构造函数对象的继承 一.什么是"非构造函数"的继承? 比如,现在有一个对象,叫做"中国人". var Chinese ...
- JavaScript面向对象编程(一)原型与继承
原型(prototype) JavaScript是通过原型(prototype)进行对象之间的继承.当一个对象A继承自另外一个对象B后,A就拥有了B中定义的属性,而B就成为了A的原型.JavaScri ...
随机推荐
- 【hbase】Unable to read additional data from client sessionid 0x15c92bd1fca0003, likely client has closed socket
启动hbase ,验证出错 Master is initializing 查看zk日志,发现Unable to read additional data from client sessionid 0 ...
- Android学习:AlertDialog对话框
AlertDialog可以生成各种内容的对话框,它生成的对话框包含4个区域:图标区,标题区,内容区,按钮区 <?xml version="1.0" encoding=&quo ...
- 【CF429E】Points and Segments 欧拉回路
[CF429E]Points and Segments 题意:给你数轴上的n条线段$[l_i,r_i]$,你要给每条线段确定一个权值+1/-1,使得:对于数轴上的任一个点,所有包含它的线段的权值和只能 ...
- axios 使用post方式传递参数,后端接受不到
参考 https://segmentfault.com/a/1190000012635783
- vue里的v-show和v-if
v-show:false 对应的是display:none:不移除dom元素.对网页渲染性能更好,适应于频繁的操作该dom的显示隐藏. v-if: false 对应 ...
- SQL语句精简版
select US.QQ,US.tel,US.username,SC.EnglishScore,SC.MathScorefrom Userinfor US right join Score SC on ...
- javascript的数组之sort()
sort()方法用in-place的算法对原数组进行排序,但不会产生新的数组.这个方法不是一个稳定的排序,默认采用的是安字符串Unicode码点进行排序的. let fruit = ['cherri ...
- vim快捷键与vi
vim与程序员 所有的 Unix Like 系统都会内建 vi 文书编辑器,其他的文书编辑器则不一定会存在. 但是目前我们使用比较多的是 vim 编辑器. vim 具有程序编辑的能力,可以主动的以字体 ...
- HotSpot虚拟机
注:如其中有不懂的名词,下面有名词解释 1.对象的创建(限于普通Java对象,不包括数组和Class对象等) (1)检查这个指令的参数能否在常量池中定位到一个类的符号引用,并检查这个符号引用代表的类是 ...
- Vue Watch 的原理 和 $nextTick() 通俗理解
网上watch和$nextTick()解释比较复杂,涉及到promise,h5的dom发生变化的新api等复杂代码,下列就是两个参考. [watch原理] [$nextTick()] 首先,看遇到问题 ...