最近一个月,可能是因为工作和生活上都非常忙,博客一直没有更新。期间也曾努力写过一篇,内容是我非常非常想写的,花了好几天的清晨时光,结果却一直构思不好,言不达意,无法驾驭文字,就暂时停下了。

由此更体会出写文章,看似简单(如今人人都基本会写字),其实非常复杂,尤其是像博客这样的,篇篇类似散文,自由灵活,要想写得随心所欲,确实还要多多书写锻炼,方有感觉。

昨天忙里偷闲,看了一会儿书,是计算机语言Ruby的发明者:松本行弘,写的《まつもとゆきひろ、コードの世界》:《松本行弘的程序世界》的日语原版。

读了几段,发现这是一本写的非常有特色,不愧为出自大师之手的书,既有一般技术文章的体系架构,有像散文集一样飘逸自如,实在让人爱不释手。此书从一开始就抓住核心问题。从程序设计的全局构想出发,从Object的特征着手,结合着松本行弘大师本人的所思所想所体会、以及计算机语言的各种历史故事,娓娓道来。

仿佛作者:松本行弘先生,就坐在你身旁,喝茶闲谈,无意之间,你已获益良多。读到兴致渐浓,我的好奇精神也被激发,于是在磁盘空间中翻箱倒柜,找出了三年前自己写的学习笔记,既做《まつもとゆきひろ、コードの世界》的读书笔记一篇,也充数博客一篇。:)

JavaScript 笔记(1) 对象概要(2009年)

(1) JavaScript 提供的Objects

Global Object Function Array String Boolean

Number Math Date RegExp Error

其中,Global 是JavaScript所提供的一些独立于(不属于)对象的功能(function)。Global, or top level functions, are functions in JavaScript that are independent of any particular object.

Object 是一切对象的Super Object 我们可以向对象追加属性,而且任何对象都可以被当作属性。We can add properties to Objects, Any kind of object can be a property.

Function 也是一个对象,这个对象是JavaScript语言构建面向对象(Object-Oriented)软件的基础 Function is a special kind of object in JavaScript, it”s a first class data type. That means we can add properties to it.

(2)Function 对象

创建一个Function 对象,可以被看做是创建了一个用户自定义的数据类型。然后,利用new 关键字,达到两个结果:结果一:创建一个新的对象,其类型是Object, 作为一个参照。结果二:执行Function。下个例子中,注意 new 这个关键字的作用。英语原文如下:The “new” keyword creates a new object (named ball_0) of type Object. It then executes: Ball( ), passing the reference to ball_0 as the calling object.

例子1:运行例子1

1
2
3
4
5
6
7
8
9
10
11
function Ball(message)   // 创建了一个Function对象:Ball( )
	{
		alert(message);
	}
	alert("the typeof Ball\( \): "+ typeof Ball);
	var ball_0=new Ball("creating new Ball");  // 创建了一个对象ball0, 注意它是Object类型
											  // 作为一个参照,参照Ball( )
											  // prints the message 执行Ball( )
	alert("the typeof ball_0: " + typeof ball_0);
	ball_0.name="ball_0'name is red ball";    // 为 ball0 对象,添加了一个属性 name
	alert(ball_0.name);                        // prints "ball_0'name is red ball"

(3)关于对象的理解

拥有属性和行为的个体,就叫做对象。将属性,行为分类,统筹管理,就叫做【分类】。

3.1 属性

比如:所有的圆,可以用:属性一:半径;属性二:圆心,来完成定义。这个定义,就是【类】,类只有概念,所谓概念,就是没有具体数值。每一个圆的半径值, 圆心值可能都不相同;这些具体的半径值,圆心值,就在产生每个对象的时候,必须被具体赋予数值,这是【实例化】。

在基于Class的面向Object的语言,比如java, C++中,class就是上述的【概念】的定义。通过【实例化】,创建出对象,并为每一个对象,分配出独立的内存,将概念中的属性,赋予具体的数值(这就是属性值),存放在独立的内存中。这就是基于Class的面向Object的语言的基石。

而在基于Prototype的面向对象的语言javascript中,任何一个对象都是以另外一个对象为模子(prototype),创建出来的。也就是说,在JavaScript语言中,其实是没有class,这种抽象的东西的,一切都是有具体数值的对象。这是JavaScript和Java, C++,在如何构造面向对象的软件上,根本的区别。而在创建的过程中,两者是一样的,为创建出来的对象,分配出这个对象独立的内存,将模子的各个属性值,一一复制到这新的内存中。

3.2 行为

行为和属性没有本质的区别,只是有一处,需要加以注意:1:一个行为所需要的内存往往很大,是一个属性的几百,几千倍。如何在【实例化】的时候,解决这个问题呢?

在基于Class的面向Object的语言,比如java中,当【实例化】的时候,不是简单的随着每个新生产的对象,为该行为分配一块内存。而是如下面的参照文章www.cjsdn.net/post/print 那样:其中的instance method 就是这里的【行为】,instance field 就是这里【属性】。

【其实,让每个instance method如同instance field一样,随着每个instance占有一块内存,这么做当然是可以的,只是Java编译器和JVM都不这么做,因为太浪费内存空间了。一个 field少则占用一个byte,多则占用数百Byte,但是method少则数个byte,多则数百Kilo Byte。Mehtod耗费的内存是field的数百倍,甚至数千倍,当然是能共享就尽量共享,比较不会消耗内存。既然JVM让一个class的所有 instance共享相同的instance method,下面两行程序代码在instanceMethod()内部时,如何区分是instance1或instance2?

instance1.instanceMethod();

instance2.instanceMethod();

因为编译器会帮我们在把instance1和instance2个别传入instanceMethod()中当作第一个参数。也就是说,任何 instance method参数的实际个数都会比表面上多一个,这个多出来的参数是由Java编译器帮我们加上去的,用来代表对应的instance。】

那么在基于Prototype的面向对象的语言javascript中呢?其解决方法,就是简简单单地,随着每个新生产的对象,为该行为分配一块内存,全部存放起来!可以查看www.permadi.com/tutorial/jsFunc/index.html 中的Example DT7 开始的说明。

(4) 创建对象

无论是基于Class的面向Object的语言,还是基于Prototype的面向对象的语言,都通过 new 关键字来创建对象,所谓创建对象,就如此(2)中的解释一下,分两步走:

1:新分配一块内存。

2:执行函数,为这块内存赋值。这个函数,就被称为构造函数。

经常会看到 this 这个变量,指的是函数的调用者。在new 关键字的两步曲中,指的就是通过【构造函数】来构建的这个对象。

在基于Class的面向Object的语言中,构造函数的作用就是【实例化】。这里,我们注意到,任何一个【实例化】出来的对象,都不能超越class所定义的属性和行为。

在基于Prototype的面向对象的语言中,构造函数的作用就是从一个已有的对象出发,并以此为模子,生产一个新的对象。正因为这样,这个新的对象,可以在生产后,自由地添加上模子所不具有的属性和行为,(当然因为是对象,所以这些新添加的属性,同时也一定是有数值的,不是一个纯粹的概念)。

(5) 属于【类】本身的

上面(3)对于【对象】的理解中,【类】是属于概念的范畴。【对象】是属于具体的,数值化的范畴。那么,有没有只有概念,而没有,或者无需具体化的事物呢?回答是肯定有,而且很多。比如,无论半径,圆心互不相同的圆,其描绘的行为draw( )可以一样。

这种只有概念,或者所有对象共性的事物,就叫做【类】本身的属性或者行为。只要有【类】,这些属性和行为就存在了,无需任何具体的对象生成。

在基于Class的面向Object的语言中,就用class 的static 关键字来表示。被称为 class field 和 class method.

在基于Prototype的面向对象的语言javascript 中, 任何一个function对象,都具有一个prototype的属性,是一个Object对象。为这个prototype 添加属性,行为,就可以实现定义【类】本身的属性和行为了。

看一下circle 的例子吧,用javascript 定义圆,并且生成两个具体的圆。

例子2:运行例子2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function Circle(radius, centre) // 创建了一个Function对象:Circle( )
	{
	  this.radius = radius;
	  this.centre = centre;
	}
	alert("the typeof Circle\( \): "+ typeof Circle);
 
	Circle.prototype.draw = function draw() 
	{
	  alert("drawing circle of raduis:"+ this.radius + "  at centre:"+ this.centre);
	}
 
	var circle1 = new Circle(10, 20);
	var circle2 = new Circle(50, 100);
 
	circle1.draw();
	circle2.draw();

以上是对于JavaScript面向对象的一些理解和总结,比较概括,和具体开发使用时的细节思路是一致的,而关于具体的细节,请参考后续的文章。这些文章对于JavaScript面向对象,解释得很清楚。


JavaScript 的online reference

JavaScript的常用语法参考,英文 www.javascriptkit.com/jsref/

关于Function对象的说明,英文 www.permadi.com/tutorial/jsFunc/index.html

关于属性和行为的说明,中文 www.cjsdn.net/post/print

上面这篇《JavaScript 笔记(1) 对象概要》是三年前写的,今天试了试上面的online reference, 发现最后一篇【关于属性和行为的说明,中文】的链接,已经不能使用了。所谓:网事如风,笔记不老,是也。:p


扩展和联想:

访客的留言(6)

  1. 不是专业人士 所以原谅我木有看懂

  2. 好清爽的主题,要是zblog的话求分享!videowoox@163.com

  3. 很不错哦,来学习下

欢迎留言