虽然 Javscript Array 是对象,typeof [] == 'object',但作为系统内置的对象类型并不同于我们自己建造的对象。
如下代码:
Array.prototype.custom=function(){ alert('custom'); }; var f=[1]; f.custom(); for(var i in f) { alert(i +' - '+f[i]); } f['0']=2; alert(f[0]); f['a']=1; //只打印用户设置属性 for(var i in f) { alert(i +' - '+f[i]); } alert(f.length);
那么看一下 我们自己模拟的 Array :
function EmulateArray() { this.length=0; } EmulateArray.prototype.substring=function(){alert(1);}; var x=new EmulateArray(); //把属性和方法都打出来了 for(var i in x) { alert(i +'-'+x[i]); }
那么总结一下,系统原生对象(特别Array) 和我们平常自己构造的对象的差异吧:
1.数组实际上是下标为属性,对应下标值为该属性值的对象,且属性能转成数字会自动转成下标数字 。(注意:平常对象属性值数字和数字字符串也不区分的,相当于数字作为属性时会转化成数字字符串)
2.for in 循环数组属性时,并不会列出数组的方法以及length属性,只会列出数组的所有用户设置属性(包括在Array类中的属性,方法),包括数字和非数字属性 ,方法
3.length 实际上等于数组对象最大的数字属性值+1
4.当访问 f[x] 时,实际上就是访问 f对象的x属性,
5.同理,对于new String(),new Date(),new Number .... 对于 for in 更不会有任何输出
ps:关于Array 类型的判断:
1.直接判断构造函数
x && x.constructor === Array
缺点:在判断来自不同window,frame的数组对象时失效
2.鸭子判断 (duck judge)
x && typeof x.length === 'number' && typeof x.splice === 'function' &&
!x.propertyIsEnumerable('length')
缺点:不能100%判断
3.简洁的平台相关判断
x && Object.prototype.toString.call(x) === '[object Array]'
缺点:无标准规定
PS: 关于 object 属性方法的枚举
javascript 中 object 的 toString() ,toLocalString(),valueOf(),hasOwnProperty(),isPrototypeOf(),
propertyIsEnumerable() 都是不能枚举的内置方法。在 for in 语句中不能遍历到这些方法属性。