前面一篇我们回顾了面向对象概念和JAVA的对象核心概念,但实际上,JAVA是一种基于类继承的面向对象语言,而javascript是基于原型的面向对象语言,我们就不纠结于基于类和基于原型的优劣,也不管它们的设计原理,我们只从使用的角度进行理解和说明。有些文章建议完全抛弃JAVA这种基于类面向对象,清空大脑,再去学习javascript这种基于原型的面向对象设计,但这是不可能的。这里有篇文章对此进行了阐述:http://www.ibm.com/developerworks/cn/web/1304_zengyz_jsoo/,大家可以去参考。
javascript有三类对象类型:本地对象、内置对象和宿主对象。
本地对象
独立于宿主环境的ECMAScript实现提供的对象。其实就是ECMAScript中定义的类,包括有:Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、EvalError、RangeError、RefereneError、SyntaxError、TypeError、URIError。
很敏感的,我看到了Object类,那么是不是其他的类都是继承自Object?没有答案,谁知道可以告诉我。我们只需要知道这些是预先定义好的类,可以直接实例化使用。具体使用方法请参考相关API文档。
内置对象
由ECMAScript实现提供,独立于宿主环境的所有对象,在ECMAScript执行时出现。只有两个对象Global和Math。根据定义,内置对象是本地对象。Math比较容易理解,你就当做本地对象一样使用即可,而且不用实例化,以为已经实例化了。重点讲讲Glaobal对象(全局对象)。
Global对象非常特殊,其实根本不存在,因为你无法使用它,那么它起什么作用呢?
它是作为 JavaScript 的全局函数和全局属性的占位符而存在,通过使用全局对象,可以访问所有其他所有预定义的对象、函数和属性。全局对象不是任何对象的属性,所以它没有名称。
在顶层 JavaScript 代码中,可以用关键字 this 引用全局对象。但通常不必用这种方式引用全局对象,因为全局对象是作用域链的头,这意味着所有非限定性的变量和函数名都会作为该对象的属性来查询。例如,当JavaScript 代码引用 parseInt() 函数时,它引用的是全局对象的 parseInt 属性。全局对象是作用域链的头,还意味着在顶层 JavaScript 代码中声明的所有变量都将成为全局对象的属性。全局对象只是一个对象,而不是类。既没有构造函数,也无法实例化一个新的全局对象。
简单的比喻可以概要性理解全局对象:在JAVASCRIPT中没有人(对象)要的属性啊、方法啊,可以简单理解为都是去全局对象的,没人要的,都是我的,呵呵。这样可以保证一种语言的一致性:ECMAScript中,不存在独立的函数,所有函数都必须是某个对象的方法。这样是不是保证了面向对象的纯洁性?也许因为此,javascript才能够被称为是面向对象的语言,起码表面上看起来是这样。
宿主对象
所非本地的对象都是宿主对象,由ECMACript实现的宿主环境提供的对象。说了半天,什么是宿主环境?宿主环境简单说就是javascript寄存的宿主的环境,如浏览器环境、服务器环境。基于此概念,我们自己定义的对象,应该就是在某个宿主环境的对象。
所有本地对象都继承自Object对象,内置对象也是本地对象,因此和JAVA一样,Object对象是根对象。
本地对象和内置对象构成了语言体系:Object、Function分别对应对象和函数概念,Array、String、Boolean、Number对应基本的数据类型,Date是时间日期,RegExp是正则对象,其他是对语言内部错误进行分类的错误对象:Error、EvalError、RangeError、RefereneError、SyntaxError、TypeError、URIError,Golbal更是重要的语言必须的对象,Math用于复杂的数学计算,为什么纳入核心语言,尚需研究。