Javascript面对对象. 第五篇
继承
继承是面向对象中一个核心的概念。其他正统面向对象语言都会用两种方式实现继承:
一个是接口实现,一个是继承。
而ECMAScript只支持继承,不支持接口实现,而实现继承的方式依靠原型链完成。
- //继承,通过原型链实现
- function Box(){ //被继承的函数叫超类型(父类,基类)
- this.name="link"
- }
- function Dest(){//继承的函数叫子类型(子类,派生类)
- this.age=25;
- }
- function Table(){
- this.level="dfsfsdf";
- }
- //通过原型链继承,超类型实例化后的对象实例,赋值给予类型的原型属性
- //new Box()会将Box构造里的信息和原型里的信息都提交给Dest
- Dest.prototype=new Box();
- Table.prototype=new Dest();
- var dest=new Dest();
- alert(dest.age)
- alert(dest.name)
- var table=new Dest();
- alert(table.age)
- alert(table.name)
如果要实例化Dest,那么Box实例中的name="link",原型中添加相同的属性name="xiao",如果有Box有就是link,没有就是xiao
- //继承,通过原型链实现
- function Box(){ //被继承的函数叫超类型(父类,基类)
- //this.name="link"
- }
- Box.prototype.name="xiao";
- function Dest(){//继承的函数叫子类型(子类,派生类)
- this.age=25;
- }
- //通过原型链继承,超类型实例化后的对象实例,赋值给予类型的原型属性
- //new Box()会将Box构造里的信息和原型里的信息都提交给Dest
- Dest.prototype=new Box();
- var dest=new Dest();
- alert(dest.age)
- alert(dest.name) //xiao
ps:以上原型链继承还少一环,那就是Object,所有的构造函数都继承自Object。而继承object是自动完成的,并不需要程序员手动继承。
- //经过继承后的实例,他们的从属关系会是什么?
- alert(table instanceof Object); //true
- alert(dest instanceof Table); //false,dest是Table的超类
- alert(table instanceof Dest); //true
- alert(table instanceof Box); //true
在javascript里,被继承的函数称为超类型(父类,基类),继承的函数称为子类型(子类,派生类)。继承也有之前的问题比如字面量重写原型会中断关系,使用引用类型的原型,并且子类型还无法给超类型传递参数。
为了解决共享和超类型无法传参的问题,我们采用了一种叫借用构造函数的技术,或者成为对象冒充(伪造对象,经典继承)的技术来解决这两种问题。
- //使用对象冒充
- function Box(name,age){
- this.name=name;
- this.age=age;
- this.family=['哥哥','妹妹','弟弟'] //引用类型,放在构造里就不会共享。
- }
- //Box.prototype.family='姐姐';
- function Dest(name,age){
- Box.call(this,name,age) //对象冒充,对象冒充只能继承构造里的信息
- }
- var dest=new Dest('link',111);
- dest.family.push('姐姐');
- alert(dest.name);
- alert(dest.family);
- var dest2=new Dest('html',111);
- alert(dest2.family);
借用构造函数虽然解决了刚才两种问题,但是没有原型,复用则无从谈起。所以,我们需要原型链+借用构造函数的模式,这种模式成为组合继承。
- function Box(name,age){
- this.name=name;
- this.age=age;
- this.family=['哥哥','妹妹','弟弟'] //引用类型,放在构造里就不会共享。
- }
- Box.prototype.run=function(){
- return this.name+this.age+"运行中...";
- }
- //构造函数里的方法,放在构造里,每次实例化,都会分配一个内存地址,浪费,所以最好放到原型里,保证多次实例化只有一个地址。
- function Dest(name,age){
- Box.call(this,name,age) //对象冒充,对象冒充只能继承构造里的信息
- }
- Dest.prototype=new Box(); //原型链继承
- var dest=new Dest('link',111);
- alert(dest.run());
还有一种继承模式叫:原型式继承:这种继承借助原型并基于已有的对象创建对象,同时还不必因此创建自定义类型。
我们学习过:
1.原型链继承,2.借用构造函数继承(对象冒充继承)3.组合继承(结合前俩种)
4.原型式继承
- //4.原型式继承
- //临时中转函数
- function obj(o){ //o表示将要传递进入的一个对象
- function F(){} //F构造是一个临时新建的对象,用来存储传递过来的对象
- F.prototype=o; //将o对象实例赋值给F构造的原型对象
- return new F(); //最后返回这个得到传递过来对象的对象实例
- }
- //F.prototype=o 其实就是相当于Dest.prototype=new Box();
- //这个字面量的声明方式,相当于var box=new Box();
- var box={
- name:'link',
- age:23,
- family:['哥哥','妹妹','弟弟']
- }
- //box1等于new F();
- var box1=obj(box);
- alert(box1.name);
- alert(box1.family);
- box.family.push('姐姐');
- alert(box1.family);
- var box2=obj(box);
- alert(box2.family);
5.寄生式继承=原型式+工厂模式
- //临时中转函数
- function obj(o){
- function F(){}
- F.prototype=o;
- return new F();
- }
- //寄生函数
- function create(o){
- var f=obj(o);
- return f;
- }
- var box={
- name:'link',
- age:23,
- family:['哥哥','妹妹','弟弟']
- }
- var box1=new create(box);
- alert(box1.name);
- //临时中转函数
- function obj(o){
- function F(){}
- F.prototype=o;
- return new F();
- }
- //寄生函数
- function create(box,dest){
- var f=obj(box.prototype);
- f.constructor=dest; //指向了Dest,没有是话指向Box
- dest.prototype=f;
- }
- function Box(name,age){
- this.name=name;
- this.age=age;
- }
- Box.prototype.run=function(){
- return this.name+this.age+"运行中。。。";
- }
- function Dest(name,age){
- Box.call(this,name,age)
- }
- //通过寄生组合继承来实现继承
- create(Box,Dest); //这句话用来替代Dest.prototype=new Box();
- var dest=new Dest('link',23);
- alert(dest.run());
- alert(dest.constructor);
Javascript面对对象. 第五篇的更多相关文章
- Javascript面对对象. 第四篇
原型模式创建对象也有自己的缺点,它省略看构造函数传参初始化这一过程,带来的缺点就是初始化的值都是一致的. 而原型最大的缺点就是它优点,那就是共享. 原型中所有属性是被很多实例共享的,共享对于函数非常合 ...
- Javascript面对对象. 第三篇
3.字面量 为了让属性和方法很好的体现封装的效果,并且减少不必要的输入原型的创建可以使用字面量. function Box(){} //使用字面量的方法创建原型对象,这里的{}就是对象,是Object ...
- Javascript面对对象. 第一篇
Javascript,有两个种开发模式: 1.函数式(过程化)2.面对对象(oop),面对对象语言有一个标志,就是类,而通过类可以创建任何多个属性和方法,而Ecmascript没有类的概念,因此它的对 ...
- Javascript面对对象. 第二篇
但是还有一个问题,就是识别的问题,因为根本无法搞清楚他们到底是哪个对象的实例. 1.构造函数 function CreateObject(name,age){ //创建一个对象,使用构造函数的对象都是 ...
- javascript面对对象编程 之继承
上一篇博客中为大家介绍了javascript面向对象编程原则的封装,今天为大家介绍继承.在javascript中没有类的概念,全部不能像c#.java语言那样.直接的用类去继承类.比方如今有比方.如今 ...
- 深入理解javascript作用域系列第五篇——一张图理解执行环境和作用域
× 目录 [1]图示 [2]概念 [3]说明[4]总结 前面的话 对于执行环境(execution context)和作用域(scope)并不容易区分,甚至很多人认为它们就是一回事,只是高程和犀牛书关 ...
- 深入理解javascript作用域系列第五篇
前面的话 对于执行环境(execution context)和作用域(scope)并不容易区分,甚至很多人认为它们就是一回事,只是高程和犀牛书关于作用域的两种不同翻译而已.但实际上,它们并不相同,却相 ...
- javascript运动系列第五篇——缓冲运动和弹性运动
× 目录 [1]缓冲运动 [2]弹性运动 [3]距离分析[4]步长分析[5]弹性过界[6]弹性菜单[7]弹性拖拽 前面的话 缓冲运动指的是减速运动,减速到0的时候,元素正好停在目标点.而弹性运动同样是 ...
- DELPHI学习---类和对象(五篇)
Classes and objects(类和对象) 类(或者类类型)定义了一个结构,它包括字段(也称为域).方法和属性:类的实例叫做对象:类的字段.方法和属性被称为它的部件(components)或成 ...
随机推荐
- Delphi ADOQuery连接数据库的查询、插入、删除、修改
http://blog.csdn.net/chinazhd/article/details/45047777 //查询记录 procedure TForm1.Button1Click(Sender: ...
- android NDK编译(导入).a文件和编译多个so文件(转)
源:android NDK编译(导入).a文件和编译多个so文件 一.编译一个静态库 libstatic_android.a LOCAL_PATH := $(call my-dir) include ...
- HTML5离线应用与客户端存储
序言 本篇文章会详细介绍使用HTML5开发离线应用的步骤,以及本地存储与cookie的一些异同,最后利用上面所学例子来实现一个购物车场景. 使用HTML5离线存储的基本过程如下: 离线检测:首先要对设 ...
- 关于mysql中触发器old和new如何更好的区别我有话要说?
1.当使用insert语句的时候,如果原表中没有数据的话,那么对于插入数据后表来说新插入的那条数据就是new,如图所示: 2.当使用delete语句的时候,删除的那一条数据相对于删除数据后表的数据来说 ...
- mark笔记
1.[cocos2dx]ccnode跟ccui节点混用时注意touch层级问题,基本不可控
- python 循环使用 while 或 for 语句实现用户名密码输错三次退出
如有错误欢迎大家指出,新手初来乍到.程序没那么复杂,是最简单的. 一.需求 编写登录文件 .py1. 输入用户名密码2. 正确,输出欢迎登录3. 当输入用户名和密码小于 3 次,输入用户名或者密码错误 ...
- iOS 属性之assign、copy、retain
参考自:http://blog.csdn.net/getchance/article/details/42213219 参考自:http://zhidao.baidu.com/link?url=Xmn ...
- NSArray和NSSet的区别
NSSet到底什么类型? 其实它和NSArray功能性质一样,用于存储对象,属于集合: NSSet , NSMutableSet类声明编程接口对象,无序的集合,在内存中存储方式是不连续的 像NSAr ...
- 10款面向HTML5 画布(Canvas)的JavaScript库
https://www-evget-com/article/2014/4/9/20799.html
- Pomelo的Filter
在pomelo中,filter分为before filter和after filter.在一个请求到达Handler被处理之前,可以经过多个before Filter组成的filter链进行一些前置处 ...