文档章节

javascript中的扩展和继承

码晒客
 码晒客
发布于 2014/12/22 16:31
字数 1285
阅读 34
收藏 0

        要理解javascript中的扩展和继承,首先要理解javascript中的原型机制,每一个javascript对象都从一个叫做prototype的原型对象继承属性、方法。原型也是普通的javascript对象,只不过原型对象只能在生成一个实例的时候作为生成该实例的参考依据,而不能直接当做实例使用,原型嘛,按照字面意思理解即可,比如盖楼房时候的设计图纸,开发web应用时产品部门给出的设计图都是原型。

        没有原型的对象为数不多,Object.prototype就是其中之一,它不继承任何属性,其他原型对象都是普通对象,都具有原型,所有的内置构造函数以及大部分自定义的构造函数都有一个继承自Object.prototype的原型,例如,Date.prototype的属性继承自Object.prototype,因此由new Date()创建的Date对象的属性同时继承自Date.prototype和Object.prototype,这一系列原型对象就是所谓的原型链。


一、javascript中的继承:

/*父类构造函数*/
function SuperClass(name,age){
     this.name = name;
     this.age = age;
}
/*子类构造函数*/
function ChildClass(addr){
     this.addr = addr;
}
/*这里可能有人会问,为什么不直接ChildClass.prototype = SuperClass.prototype?
*这是因为,如果这样做的话,给ChildClass.prototype添加的方法也会在SuperClass.prototype中出现,
*也就是说给子类添加的实例方法会动态添加到父类实例中,这不符合继承的含义,继承要求给子类实例添加的
*方法只能出现在子类实例中而不能出现在父类实例中,所以ChildClass.prototype = new SuperClass()
*才符合真正意义上的继承
*/
ChildClass.prototype = new SuperClass('Lucy',23);
//确保ChildClass实例的类型还是ChildClass,如果不加这句,生成的对象的constructor属性为SuperClass
ChildClass.prototype.constructor = ChildClass;
/*child对象继承了SuperClass对象的属性*/
var child = new ChildClass('British');
console.log(child);
输出结果如下:
ChildClass { addr="British", name="Lucy", age=23}

        上面的代码仅仅是两个简单的构造函数,但是我们一定要清楚他们的底层原理以及执行过程,比如SuperClass构造函数,首先它是一个函数,函数也是对象,不同的是,函数对象是由Function的构造函数创建的,像Function,Object,Array,Date,RegExp等对象都是由本地代码创建并随着浏览器启动就已经在内存中存在的,当我们用function SuperClass(){}这种方式声明一个函数时,就会调用Function对象的构造函数,Funciton构造函数会执行类似如下的代码:this.prototype={constructor:this},看到这里是不是恍然大悟呢,javascript中每个函数在定义之后都会默认的有一个prototype属性,此时prototype只是一个最简单的对象,没有任何属性和方法,只有一个constructor属性,而且constructor就是这个函数本身,

function SuperClass(){}
function ChildClass(){}
var c = new ChildClass();
var c1 = new ChildClass();
console.log("c的构造函数" + c.constructor);
console.log("c1的构造函数" + c1.constructor);
console.log("将c的constructor属性改为SuperClass");
c.constructor = SuperClass;
console.log("c的构造函数" + c.constructor);
console.log("c1的构造函数" + c1.constructor);

运行结果如下:
c的构造函数function ChildClass(){}
c1的构造函数function ChildClass(){}
将c的constructor属性改为SuperClass
c的构造函数function SuperClass(){}
c1的构造函数function ChildClass(){}

        所以我们回过头来再看看new ChildClass()的执行过程,首先new会根据后面的类名ChildClass找到ChildClass这个函数对象,然后在找到这个函数对象的prototype属性所指向的对象,在这里是{constructor:ChildClass,name:'Lucy',age:23},再将这个对象拷贝一份,(为什么说拷贝一份呢,依据就是上面的测试代码) 然后根据constructor找到ChildClass函数,开始对拷贝的对象进行初始化,最后就得到了一个类型为ChildClass的新对象。新对象创建之后,如果ChildClass.prototype所指向的原型对象发生了改变,比如添加了方法,由于javascript是动态的语言,所以那些所有继承自ChildClass.prototype的对象都会随之发生改变。

        从以上叙述中可以得出,如果构造函数不同,实例对象的类型有可能相同,所以,javascript中的类不是由构造函数决定的,而是由原型决定。即原型才是类的唯一标示,

二、javascript中的扩展(extend)

     扩展和继承的不同在于,继承自父类的子类对象,当父类的prototype发生改变时子类对象中继承过来的属性方法都会改变,比如给上述中的SuperClass.prototype添加了m方法,SuperClass.prototype.m = function(){};那么child对象也会有这样一个方法,child.m();

SuperClass.prototype.m = function(){  
    console.log('m() is running!');
}
child.m();
输出结果:m() is running!


而扩展,extend意思是将原有对象中的属性、方法复制到一个新对象中,这个新对象和原有对象就没有关系了。

function extend(o,source){
     for(prop in source){
          o[prop] = source[prop]
     }
     return o;
}


这是一个简单的继承函数,将source中的属性,方法复制到o中。


© 著作权归作者所有

码晒客

码晒客

粉丝 0
博文 6
码字总数 7117
作品 0
昌平
程序员
私信 提问
【Javascript】- Prototype 原型

JS Prototype 原型 prototype:原型:如果对象B是建立在对象A的基础上,那么A为B的原型,类似Java里面的父类和子类的关系,B不仅可以使用A定义的属性和方法,还可以进行额外的功能扩展,经常...

ZeroneLove
03/01
10
0
JavaScript 中的继承:ES3、ES5 和 ES6

选择一种继承方式 JavaScript 是一门动态语言,动态意味着高灵活性,而这尤其可以体现在继承上面。JavaScript 中的继承有很多种实现方式,可以分成下面四类: Mixin 模式,即属性混入,从一个...

天方夜
2018/10/30
0
0
再谈 javascript 面向对象编程

前言:虽有陈皓《Javascript 面向对象编程》珠玉在前,但是我还是忍不住再画蛇添足的补上一篇文章,主要是因为javascript这门语言魅力。另外这篇文章是一篇入门文章,我也是才开始学习Javascr...

aoniao
2012/02/28
4.5K
22
JavaScript模拟Java类继承

javascript采用原型继承的方式继承一个类(javascript没有类这个概念,暂时这么称呼吧),但一些使用过Java的程序员可能习惯使用经典的类继承,但javascript原生并不支持这种方式,因此需要手...

smalldragonluo
2014/06/17
193
0
写的一个轻量级javascript框架的设计模式

公司一直使用jQuery框架,一些小的项目还是觉得jQuery框架太过于强大了,于是自己周末有空琢磨着写个自己的框架。谈到js的设计模式,不得不说说js的类继承机制,javascript不同于PHP可以轻松...

thinkyoung
2014/12/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

golang-字符串-地址分析

demo package mainimport "fmt"func main() {str := "map.baidu.com"fmt.Println(&str, str)str = str[0:5]fmt.Println(&str, str)str = "abc"fmt.Println(&s......

李琼涛
今天
4
0
Spring Boot WebFlux 增删改查完整实战 demo

03:WebFlux Web CRUD 实践 前言 上一篇基于功能性端点去创建一个简单服务,实现了 Hello 。这一篇用 Spring Boot WebFlux 的注解控制层技术创建一个 CRUD WebFlux 应用,让开发更方便。这里...

泥瓦匠BYSocket
今天
6
0
从0开始学FreeRTOS-(列表与列表项)-3

FreeRTOS列表&列表项的源码解读 第一次看列表与列表项的时候,感觉很像是链表,虽然我自己的链表也不太会,但是就是感觉很像。 在FreeRTOS中,列表与列表项使用得非常多,是FreeRTOS的一个数...

杰杰1号
今天
4
0
Java反射

Java 反射 反射是框架设计的灵魂(使用的前提条件:必须先得到代表的字节码的 Class,Class 类 用于表示.class 文件(字节码)) 一、反射的概述 定义:JAVA 反射机制是在运行状态中,对于任...

zzz1122334
今天
5
0
聊聊nacos的LocalConfigInfoProcessor

序 本文主要研究一下nacos的LocalConfigInfoProcessor LocalConfigInfoProcessor nacos-1.1.3/client/src/main/java/com/alibaba/nacos/client/config/impl/LocalConfigInfoProcessor.java p......

go4it
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部