javascript中的原形继承(一)

    “面向对象”有三种基本特性,即封装、继承和多态。一般来说,三个特性都完全满足的话,我们称之为“面向对象语言”,而称满足部分特性的语言为“基于对象语言”。

    “对象系统”的继承特性,有三种实现方案,包括基于类、基于原型和基于原类。而javascript中没有采用我们常用的类继承体系,而是使用原型继承来实现对象系统。因此javascript中没有类,而采用一种名为“构造器”的机制来实现类的某些功用。

        关于这个话题我想从空对象与空的对象来开始讨论原型继承,空对象(null)我们要先明确它的定义它是一个保留字,属于对象类型而且对象是空值,null对象可以参与运算,但因为他没有属性也没有方法,同时也没有原型,所以相关的调用都会失败。由于它并不是object()构造器实例而来,因此instanceof()运算会返回false。而所谓空的对象,就是一个标准的、通过object()构造的对象实例,例如obj=new object();空的对象有对象的一切属性。

        下面我们来讨论一下原型继承的基本属性,在javascript对象系统的实现来讲,对象并没有原型,而构造器有原型,对象只有“构造自某个原型”的问题,并不存在“持有某个原型”的问题。原型其实也是一个对象实例。原型的含义是指:如果构造器有一个原型对象A,则由该构造器创建的实例都必然复制自A,而且我们还要明确一个概念就是空对象是所有对象的基础,我们用下面的代码来考察一下最基本的object()构造器:

           

    //取原型对象

    pro =Object.prototype;

    //列举对象成员并计数

    var num=0;

    for(var n in pro){

    num++;

}

    //显示计数:0

    alert(num);

可见,object()构造器的原型就是一个空对象。那么这有什么意义呢,这意味这

    obj1=new Object();

    obj2={};

无非是从object.prototype上复制出一个“对象”的映像,但这种方法每复制出一个实例,新的实例与原型占用了相同的内存空间,所以这种方法非常不经济,另一种策略是欺骗系统的技术:写时复制。这种欺骗的典型示例就是操作系统中的动态链接库,它的内存区总是写时复制的,这种方法的远离就是当需要写对象的属性的时候,我们就复制一个原型的映像出来,并使以后的操作指向该映像。

    显然上面的规则只是讲了对象的形成过程,而没有讲到构造过程,其实函数首先只是一个函数,尽管他有一个prototype成员,但如果每生命一个成员都先创建一个对象实例,并使prototype指向它,那么也不经济,所以我们事实上可以认为protytope在函数初始化时候根本是无值的,实现上可能是下面的逻辑

    var _proto_ =  null;

    function get_prototype(){

        if(!_proto_){

            _proto_=new Object();

            _proto_.constructor = this;

        }

    return _proto_;

    }

所以,函数只有在需要引用到原型的时候,才具有构造器的特性。当一个函数的prototype有意义时,它就变成了一个‘构造器’。这是当new一个实例时,引擎会在构造一个对象,并使该对象的原型指向prototype的属性就可以了

         

你可能感兴趣的:(JavaScript,null,false)