欢迎关注微信公众号:全栈工厂
本文主要参考
一直以来穿梭于前端后端之间,突然间发现自己对JS的数组和对象操作有些混淆了,因为他们的操作方式太像了。例如数组 var arr = [1,2,3,4,5]
和对象 var obj = {'0':1, '1':2, '2':3, '3':4, '4':5}
:
arr[3]
obj[3]
都会输出4
arr[5]=6
obj[5]=6
都会给变量添加新值6
而且,在PHP中$arr = [1,2,3,4,5]
与 $obj = ['0'=>1, '1'=>2, '2'=>3, '3'=>4, '4'=>5]
完全等价,这更加剧了我的头晕!今儿个势必搞清楚~
这俩货区别到底在哪里?
带着这个疑问,我在 ECMA-262标准 9.4.2节中找到了答案:
这段话翻译过来意思是:
数组其实是一个对数组索引属性值做特殊处理的一个"特殊对象",在这个“特殊对象”中,如果一个属性的属性名满足数组索引属性的条件,那么我们称这个属性为一个数组元素。每一个数组对象默认会有一个小于 232的非负整数属性
length
,length
属性在数值上大于所有数组索引值,每当数组对象添加或者更新属性的时候,其他属性甚至会被调整来让length
属性尽量保持不变;除非新添加的属性是一个数组索引length
属性值才会被修改,并且新调整的值在数值上大于所有数组索引值。如果length
属性被修改,那么数组对象中所有大于等于length
属性值的数组索引属性将会被删除(从原型中继承的数组索引属性不会有影响)。
注:数组索引属性:如果一个字符串属性P在强转为无符号整形(ToUint32)后小于(232−1)并且强转后的值再转为字符串(ToString(ToUint32(P)))与原字符串(P)相等,那么属性P为数组索引属性。
数组对象会自动生成length
属性。
数组对象除了提供[[DefineOwnProperty]]选择定义内部方法以外,还提供了9.1标注的所有必要内部方法。
通过上面这段话以及已经掌握的知识,我们可以总结出JavaScript中数组与对象的区别与联系主要有:
① 数组是一个特殊的对象,数组具有对象的所有性质;
② 数组可以是一个有序的数据集合,而对象是无序的(因为数组是一个特殊的对象,所有如果按照对象的方法操作数组,那么数组也可以是无序的);
③ 数组中的属性会区分数字字符串和普通字符串,如果是数字字符串且强转后数值小于(232−1),那么我们称该属性为索引属性,数组对索引属性会区别操作;
④ 数组默认会有一个length
属性,该属性与数组索引属性的操作密切关联,该属性具有以下几个特点:
1.length
属性值始终大于数组中所有索引属性值(所以如果数组中索引属性值是不连续的,那么length
值并不能反映数组中元素的个数);
2.如果直接对数组中length
属性赋值,那么数组中所有大于等于length
属性值的索引属性都会被删除(原型中继承的索引属性除外)
注:文中如有任何错误,请各位批评指正!