Spidermonkey学习笔记

Javascript的对象模型

    学习c++的人可能都看过c++对象模型这本书。在我们的映像中面向对象总是与类和实例这样的概念挂钩。但是很多脚本语言也是面向对象的,它们的对象模型与c++这种语言是很不相同的。我觉得在使用某门语言的时候,不能局限于对语言的应用,应该去了解和思考这门语言的特征、背后的思想以及它的实现模型等,这样才能举一反三、知其然知其所以然——在众多技术中做一个神志清醒的人,不至于茫然混乱。

    最近需要弄出一个javascript的脚本解释器。研究了一下spidermonkey。在研究的过程当中需要学习一些东西。所以我打算写一系列的笔记(能有多少不知道,看时间充不充裕)。

    这是本系列的第一篇,探讨一下javascript的对象模型(JavaScript 1.5),并于c++等语言做一个比较。

 

1.       javascript简介
起源: Netscape
特征:对象脚本语言,是ECMAScriptECMA-262规范)的超集。广泛应用于web和桌面应用(尤其前者       )。

 

2.       Class-Based vs. Prototype-Based

javascript的面向对象与c++java中的面向对象是不同的。前者称为基于原型的(prototype-based),而后者则是基于类的(class-based)c++java等语言构建在两个重要的概念上:类和实例。类是抽象,而实例则是具体的实现,二者有严格的区分。但是javascript中只有对象(object)这个概念。任何对象在创建时或运行时都拥有自己特定的属性,而且它随时可以作为其它对象的原型。你可以把对象看成是一个智能的数据集。

       calss-based语言中,需要单独的代码对类进行定义,然后在另外的地方通过构造函数初始化具体的实例。javascript类定义和构造函数发生在同一地方,因为它只有对象这一概念,不存在抽象的类。

       class-based语言中,对象通常在编译时就已经创建好了,对象在运行期是不能添加、删除属性或修改属性类型。javascript在运行期还能对对象做各种修改,而且如果这个对象是另一个对象集合的原型,这种修改还能扩散到以其作为原型的那些对象。

异同总结     

Class-based (Java)

Prototype-based (JavaScript)

类和实例是不同的实体

都是实例

定义对象

然后使用构造函数创建实例

使用构造函数在创建的同时定义

构造函数只是一个普通函数,没有特殊之处

使用new创建

使用new创建

使用继承定义语法来创建继承类

通过把一个对象作为原型赋给一个构造函数

通过继承链继承属性、方法

通过原型链继承属性

类描述了实例的一切,实例不能动态添加、删除、修改属性类型。

构造函数或对象原型初始化一组属性。可根据需要在运行期动态添加、删除、修改书信类型。

 

3.       对象模型的简单实例介绍

浏览器等应用程序通常都内建了自己的javascript对象。当然web开发人员可以定义自己的对象。

       javascript语言中,一个对象实际上是一张表(可能java也是,因为我不是很熟java,所以不肯定)。既然是一张表,那么可以把其看成是一个数组,实际上,javascript中数组和类之间有如下密切关系(假设有对象myCar):

       我们给其属性赋值

    myCar.make = "Ford"

    myCar.model = "Mustang"

    myCar.year = 69;

           等介于

myCar["make"] = "Ford"
    
    
myCar["model"] = "Mustang"
    
    

 myCar["year"] = 67;

甚至

myCar[0] = "Ford"
    
    
myCar[1] = "Mustang"
    
    

myCar[2] = 67;

       有上面的关系,我们大致可以得知对象在javascript解释器中中是什么摸样了:

类型

名称

指针/

属性/对象

make

字符串地址

属性/对象

model

字符串地址

属性/对象

year

字符串地址

方法

displayCar

函数的地址

       所以,我们可以通过下面的函数来显示一个对象所有的属性值:

function show_props(obj, obj_name) {

    var result = ""

    for (var i in obj)

        result += obj_name + "." + i + " = " + obj[i] + "/n"

    return result;

}

       这里说说对象的方法。对象的方法实质上我普通的函数没什么区别。你可想定义一个标准的函数一样定义对象的方法,然后把二者关联起来,使用如下语法:

object.methodname = function_name

比如:

function displayCar() {

   var result = "A Beautiful " + this.year

                + " " + this.make + " " + this.model;

   pretty_print(result)

}

       创建对象

       分为两个阶段:1.写一个构造函数。2.使用new创建对象。

       function car(make, model, year) {

        this.make = make;

         this.model = model;

        this.year = year;

this.displayCar = displayCar;

}

       mycar = new car("Eagle", "Talon TSi", 1993);

       根据这个实例,我们可以归纳:javascript是完全基于对象的语言,而c++这种语言是只能说是面向对象的。

             

4.       创建对象

参考下面的原型链图(注意每个对象都包含两个属性/方法:constructor,prototype)。

当我们写下代码:

Function car(){}

Javascript解释器遇到function关键字后,用Functionfunction.prototype创建了car这个对象,用Objectobject.prototype创建并初始化了CarPrototype这个对象。因此我们认为FunctionObject以及他们的原型是metaclass级别的对象,俗称“天父,天母”。

       理解javascript需要理解天父、天母这两条线。

      

     所以每一个具体的对象的创建,都是分两步,第一步:按照它的原型分配一块内存;第二步:使用它的构造function初始化这部分内存。

       当我们写下:

       var car1=new Car();

       则使用Car对象和CarPrototype对象创建Car1

       我们可以使用typeofinstanceof运算符。比如:

       Document.writeln(typeof(Car));

       Document.writeln(typeof(Car.prototype));

Document.writeln(car1 instanceof Car);

 

5.       对象模型的简单实例介绍(续)

javascript有五个原始类型:Undefined,NULL,Boolean,Number,String(实际上应该还包括天父天母同志)。由于这些原始类型占据的空间是固定的,所以它们存储在较小的内存区域--栈中,如果一个值是引用类型的,那么它的存储空间将从堆中分配。

javascript中的对象全是引用类型(好像java中也是这样吧)

var o= new Object()

o是一个引用,也是一个对象

javascript中的函数对象也全是引用类型

javascript的对象模型用得最广的是混合的构造函数/原型方法,:

function Car(sColor, iDoors, iMpg) {

    this.color = sColor;

    this.doors = iDoors;

    this.mpg = iMpg;

    this.drivers = new Array("Mike", "Sue");

}

Car.prototype.showColor = function () {

    alert(this.color);

};

var oCar1 = new Car("red", 4, 23);

var oCar2 = new Car("blue", 3, 25);

oCar1.drivers.push("Matt");

alert(oCar1.drivers);    //outputs "Mike,Sue,Matt"

alert(oCar2.drivers);    //outputs "Mike,Sue"

上例就是一个混合的构造函数/原型方式,每个new出来的对象都拥有自己的属性,但每个对象都指向相同的函数showColorshowColor被每个对象共享(在原型中,他是个引用)。如果你想该处创建的对象一个默认属性值呢?设置原型对象的属性为一个默认值即可,比如:

Car.prototype. color=default_color;

 

 

 

参考资料:    Core JavaScript 1.5 Guide

                    深入浅出javascript对象模型

                     The JavaScript Object Model

You can search them online.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值