从这个部分开始,讲述的都是js独特的东西,你会发现与java等面向对象语言完全不同,是理解js必须掌握的非常重要的概念。
对象和数组是js里最重要的两种数据类型,为什么两者要放在一起讲且认为是最重要的呢?js中对象和数组一样,是值的集合,区别在于,对象是已经命名的值的集合,数组是数据的一组有序的集合。简单的看,对象的数据值是已经命名了的,类似字典键值对的形式,通过这些名字来存取数据。数组数据值没有命名,但可通过下标来访问(数组大多数语言中的数组类似,且更加宽松,和PHP类似,一个数组可构建几乎一切数据形式)。
如何创建对象
方法1:是最简单最直接的方法,使用对象直接量,一个花括号包含的一对对属性名称和值的列表。注:形式上和python的键值对组成的字典形式上一样。
var empty={}; //定义了一个没有任何属性的对象empty; var point={x:0,y:0}; //定义了一个坐标类point,x、y值都为0; var homer={ "name":"Homer Simposn", "age":34; "married":flase; 'email':"homeer@example.com" }; //定义了一个复杂一些的宅男类,包含数个属性。
方法2:用new运算符创建具体的对象,new后面跟着一个构造函数。new运算符应用于已经定义的类和js内置类,按照OOP,new是创建了一个对象实例,js没有这么严格的概念,统称为对象。
var a=new Array(); // 创建一个数组对象,构造行数是function Array(){} var d=new Date(); // 创建一个日期对象,构造行数是function Date(){} var o=new Object(); //创建一个空对象,构造函数式function Object(){}
对象的属性
对象的属性存取和其他语言一样,使用"."运算符访问和存取对象的属性。
js是动态语言,不用使用单独的反省对象就能够列出对象成员,列出对象属性方法是使用for/in循环遍历:
1 function DisplayPropertyNames(object){ 2 var names=""; 3 for(var name in obj) names+=name+" "; 4 alert(names); 5 }
上篇运算符中提到可以用in运算符来检查属性是否存在。
if("x" in o ) o.x=1; //如果O的属性x存在,设置值为1
还有一个方法不需要用 in 运算符。
if(o.x!==undefined) o.x=1;//当属性不存在,会返回undefined.
但要注意,如果 o.x=undefined;形式已经定义了属性x,上面代码将无法按照预期工作。
使用delete运算符可方便的删除属性,但严格模式不赞成使用。
delete o.x;
用"[]"运算符存取对象属性
除了"."运算符,还有一种更灵活且常用的属性存取方式,数组的[]运算符。
Object.property; // "."运算符方式 Object["property"]; // 数组"[]"运算符方式
前面讲到,对象是有名字的键值对数据集合,这和其他语言的map、hashtable、dirct等键值对方式对象一样。因此,可以通过属性的键名称字符串来存取属性值,这种方式更加灵活且常用。
原因在于,js是弱对象语言,对象的属性是可随时增加和修改的,利用此特性,可以写出非常灵活而强大的程序,在还不知道属性的情况下,动态的构建对象。在属性名称不可预知的情况下,可以动态的使用"[]"运算符来存取属性。
var stock_name=get_stock_name_from_user(); //从用户输入中获得股票名称 var shares=get_number_of_shares(); portfolio[stock_name] = shares; // 股票名称是用户输入的,程序事先无法获知,使用"[]"运算符可动态的设置股票的数量
当对象采取这种方式,常常也会被称为关联数组(不叫对象了,难道这就是js的复杂性)。
对象通用属性和方法
和其他OOP语言一样,js所有对象都继承自Object类,因此都继承了Object类的属性和方法,称为通用属性和方法。
- constructor属性:它引用了初始化对象的构造函数,该属性可用来确定对象的类型;
- toString()方法:和JAVA一样,该方法用于在打印或者转换对象为字符串的时候,输出的字符串;
- toLocaleString()方法:对象的本地化字符串表示,其他和toString()方法一样;
- valueOf()方法:当js需要把一个对象转换为某种基本数据类型才调用;
- hasOwnProperty()方法:判断是否非继承而来的属性;
- propertylsEnumerable()方法:可枚举的非继承属性,鉴于对象用户定义属性总是可以枚举的,因此方法返回值总是和hasOwnProperty方法相同;
- isPrototypeOf()方法:判断对象是否参数的原型对象,如:
var o={}; Object.prototype.isPrototypeOf(o); // true
数组
js数组大部分和JAVA数组类似,只有几点区别:
- js数组长度是任意的,不是定长的;
- 不支持定义多维数组,但数组可包含数组元素,模拟多维数组;
- js数组元素支持异构数据类型,这点很灵活。JAVA数组是否支持不记得了:)
数组定义了一些有用的方法,这些方法比较类似python中提供的方法,请参考文档,这里不一一列举。