JavaScript 对象引用类型(穿插了很多与Python的比较)

    在JS中,对象引用类型共可分为以下几种,Object、Array、Date、RegExp、Function,以及类似于JAVA包装机制的Boolean、Number、String,还有内置对象Global、Math。以下将分别介绍这些引用类型。

    1:Object 类型。创建Object对象有两种方式

    

var obj=new Object();
obj.name="ted";
obj.age=21;

 

   这种方式和Python的动态属性赋值很相似

    第二种方式,官方术语称之为对象字面量的方式,这也是官方推荐的方式,因为它更有封装的味道。

   

var obj={
    name:"ted",
    age:23
}

 

    在利用这种方式来定义对象类型的时候,不会调用到Object类型的构造函数(FireFox除外)。事实上如果你改写成:

   

var obj={};
obj.name="ted";
obj.age=23;

 

   也是可以的,只是这样改写后,将只会具有默认属性了。

 

   2:Array类型

     JS中的Array类型,虽然起名为“数组”,但事实上它更接近于Python的列表类型。Array类型对象可以放置任意的基本类型,对象,还可以自如的自动伸展(不需要调用任意方法,这点在Python中不具备)。创建Array类型的对象有两种方法:

    第一种方式,采用new操作符。

   

var array=new Array();
//或者直接指定数组所具有的元素,但是需要注意一个小陷阱
var arary=new Array(3);
var array=new Array("test","love");
//上述两种方式稍微有点不同
//第二种方式创建了一个具有初始长度为3个的数组
//而第三种方式创建了一个具有初始长度为2,元素为test和love的数组

 

  第二种方式,称为数组字面量方式,非常类似于Python的列表类型定义。

  

var array=["test","love"]

 

 只是稍有不同的是,在JS里,不可以在元素的末尾添加上逗号",",在IE和Opera浏览器中这样做会报错。

    

var array=["test","love",]//在IE或者Opera解释的时候出错

 

而在Python中则没有这种问题,甚至还可以利用这一点创建一种称之为函数副作用的特性。例如:

 

a=(1);#将1作为一个整数数值类型传给a
a=(1,);#传递一个元组类型给a,长度为1,元素为整数对象1

  

但是JS里的数组可以任意伸展,根本原因在于数组的length属性不同于Java或者Python的数组长度属性,在JS里它不是可读的。例如:

  

var a=[1,2]
alert(a.length)//输出2
a[2]=5
alert(a.length)//输出3

 

   而在Python中,这只会导致和JAVA一样的数组越界错误(只是Python的提示信息会更友好)。

   所以在JS中,可以利用这一点,做一些很简单的事情,例如:

   

 var a=[1,2]
 a[a.length]=3
 a[a.length]=4
 alert(a)//输出1,2,3,4
 而a[100]=5
 alert(a.length)//输出100,其中从4到98在访问的时候都会是undifined值

  

   同时在JS中数组类型Array也同时具备栈和队列的类型,这一点和Python的列表类型也非常相同。在JS中模仿栈的特性是分别调用push(Object... args)和pop()方法,前者可以接受任意数量的成员,而后者将自始至终弹出栈顶元素。例如:

  

var a=[1,2];
a.push(3,4);
alert(a);//输出1,2,3,4
var item=a.pop();
alert(item);//输出4

 

   而对应的Python代码是:

    

a=[1,2];
a.append(3);
a.append(4);
print a;#输出1,2,3,4
b=a.pop();
print b;#输出4

     JS里数组对应的队列特性,则利用到push和shift,后者从队列头(对应于数组就是第一个元素)移除一个元素,例如:

var a=[1,2];
a.push(3,4);
alert(a);//输出1,2,3,4
var item=a.shift();
alert(item);//输出1

 

       而对应在Python中,则是这样:

  

a=[1,2]
a.append(3);
print a;#输出1,2,3
b=a.pop(0);
print b;#输出1

 

     可见在python中去实现堆栈和队列用到的都是同一个方法,只是pop方法不同。pop方法不指定参数将默认弹出最后一个元素。下面是Python的pop方法描述:

    

pop(...)
L.pop([index]) -> item -- remove and return item at index (default last)

  

        在JS中要对数组排序的方法,有两种:

        第一种reverse()方法,这种方式将直接反转

        第二种方式sort(),但是需要注意的是它把所有的对象当做字符串,如果不是,则将调用其toString()方法。

       

var a=[1,5,10,15,2]
a.sort();
//输出1,2,5,10,15吗?不!
alert(a);//输出1,10,15,2,5

 

        如果想让它们按照数值类型来排序的话,则需要指定一个比较函数,例如:

  

function compare(num1,num2){
   return num1-num2;//升序排序
  //return num2-num1;//降序排序
}
var a=[1,5,10,15,2];
a.sort(compare);
alert(a);//这回可以正确的输出1,2,5,10,15了

    

      而在Python中则没有这种问题,理由很简单Python一切都是对象,在进行任何比较的时候,默认都调用了它们的内置函数__cmp__(),而Python的基本类型对它实现的很好,所以这里无需普通程序开发员操心。

   

      同样JS里的数组也支持序列切分(序列切分对原有数组没有任何影响),实现方法是slice方法,默认将返回从第0项到最后一个元素的全部数组元素。也可以指定负数,只需要注意的是-1从最后一个元素算起,而最开头的元素称为-length-1,例如:

     

var a=[1,5,10,15,2];
alert(a.slice(1,4));//输出5,10,15
alert(a.slice(-3,-2));//输出10

 

   而在Python中,则支持的更彻底更简便。Python中提供了称为冒号:这样的切分符号。上述方法可以简化为:

   

a=[1,5,10,15,2]
print a[1:4];#输出5,10,15
print a[-3:-2];#输出10
#而且不光是列表,只要是序列类型都支持这样做,包括字符串和元组

 

   写到这里,大家不妨再考虑下更早的JAVA语言,你会发现JAVA里面的数组只是一个改装版的C风格的数组,它缺少了太多的本该属于面向对象的函数特性。

posted @ 2011-06-12 09:42  老去的JAVA程序员  阅读(153)  评论(0编辑  收藏  举报