Ryan.Sun

Love is everything

导航

JavaScript中的对象与构造器

Posted on 2011-04-05 17:09  Ryan.Sun  阅读(1105)  评论(0编辑  收藏  举报

一、对象从何而来

首先来看什么是对象,搜索wiki百科可以得到解释,在面向对象(Object Oriented) 的软件中,对象(Object)是某一个(Class)的实例(Instance) ,因此说有对象之前必须先有类型,然后再将类型实例化就得到了对象。

那么在JavaScript中,类型不是通过如java的声明的方式定义,而是通过function的方式获得的,如

   1:  function DemoClass(){}
   2:   
   3:  var x = new DemoClass();

注意:这个顺序不能改变,必须先有function才能获得对象,否则会出现脚本错误,这是因为JavaScript的解析器是按顺序解析的,如果使用了还未被解析的function就会出现错误,由于这类function用来构造对象,把这类function叫做构造器

二、构造器的结构

每个构造器都有prototype属性,这个属性的结构是字典,可以任意添加名-值对组合,如

   1:  function DemoClass(){}
   2:   
   3:  DemoClass.prototype.Name = "DemoClass";
   4:   
   5:  DemoClass.prototype.IsNum = function(){return ture;};

同时每个构造器的prototype属性都有一个constructor属性指向构造器自身,构造器的prototype的类型为Object

三、对象的结构

每个对象都有__proto__只读属性,这个属性指向构造器的prototype属性。

除此之外,对象还有一个隐藏的内部属性,这个属性结构也是字典,可以任意添加名-值对组合

因此修改了构造器的prototype字典,所有由该构造器生成的对象的属性就会发生改变,如果只是对一个对象实例修改了属性,其他对象实例不会受到影响,如

   1:  function DemoClass(){}
   2:  DemoClass.prototype.Name = "DemoClass";
   3:  DemoClass.prototype.IsNum = function(){return ture;};
   4:  var x = new DemoClass();
   5:  var y = new DemoClass();
   6:  DemoClass.prototype.Name = "DemoClass1"; /* x.Name == y.Name */
   7:  x.Name = "DemoClass2"; /* x.Name != y.Name */

四、对象属性的读取和修改

由于每个对象实际上都会有两个字典,因此必然要有先后顺序,而且读取和修改的策略也不同

读取时,首先从对象自身的字典中读取,若找到则返回,未找到时再从__proto__指向的字典中查找,若找到则返回,若未找到则返回undefined。

修改时,直接向对象自身的字典中添加或修改,不对__proto__指向的字典操作

这样的策略保证了对单个对象属性的修改不会影响到其他对象,同样的对象在不同的运行时环境里就有了不同的行为即“动态性”。

五、再看构造器

看如下代码

   1:  function DemoClass(){}
   2:  DemoClass.prototype.Name = "DemoClass";
   3:  function DemoClass1(){}
   4:  DemoClass1.prototype.Name = "DemoClass1";
   5:  var x = new DemoClass();
   6:  var y = new DemoClass1();

声明两个构造器并且给每个构造器都实例化了对象,通过测试发现,两个构造器的prototype所指的字典并不相同,但是类型都为object

从这些可以看出,构造器被调用时,其prototype属性是一个object的实例,下面是用C来描述构造器和对象的结构

   1:   //构造器
   2:  struct Constructure{
   3:      object prototype;
   4:      Constructure(){
   5:           this.prototype = new object();
   6:           this.prototype.constructor = this;
   7:      }
   8:  }
   9:  //对象
  10:  struct Instance{
  11:       Constructure* __proto__;
  12:       object innerdict;//内部的字典
  13:       Instance(){
  14:           this.innerdict = new object();
  15:           this.__proto__ = JSRuntime["Constructure"];//通过运行时获取构造器地址
  16:       }
  17:  }