类数组对象啊,被人问到它跟真正的数组对象有什么差别啊?说不上来就老埋汰了,只知道函数的arguments对象是个类数组对象,也有length属性,其他呢?干货奉上:
首先先说说数组吧:
1,当有新的元素添加到列表中时,会自动更新length属性。
2,设置length为一个较小值将截断数组。
3,从Array.prototype中继承一些有用的方法。
4,其类属性为“Array”。
这些类数组对象可以进行遍历,但是不能使用数组方法,也不用期望length属性有什么特殊的行为,看看类数组对象是怎么生成的吧?
var a = {}; var i = 0; while(i<10){ a[i] = i*i; i++; } a.length = i; var total = 0; for(var j = 0;j<a.length;j++){ total += a[j]; }
这里其实生成了一个对象a,里面有key,value的键值对,key值是从0到9,还有一个length属性,这个length属性是定义好的,除非手动更新,否则不变的。
之前函数的arguments对象就是一个类数组对象,在客户端javascript中,一些DOM的方法:如document.getElementsByTagName()的结果也是返回类数组对象。如何检测类数组对象呢?
首先先确定是个对象,不是null或者undefined,它的length是有限非负整数,typeof o === 'object';
好像数组也符合这个,因为类数组对象没有继承Array.prototype,应该再加上Object.prototype.toString.call(o) !== 'Array',就是个类数组对象了。
划重点!!!来来来!!!
虽然类数组对象没有继承Array.prototype,没有什么join,slice,pop,push等等方法,但是忘记call和apply神器的用法了么?代码如下:
var a = {"0":"a","1":"b","2":"c","3":"d",length:4}; Array.prototype.join.call(a,'+'); //"a+b+c" Array.prototype.slice.call(a,0) //['a','b','c','d'],真正数组的副本啊
这里出个题了,怎么将一个类数组对象转化为一个真正的数组对象???
答案就是:a = Array.prototype.slice.call(a,0),再用Array.isArray(a)检测类型,true,哈哈哈哈
Part two:作为数组的字符串
字符串的行为类似于只读数组,除了用charAt()访问单个字符以外,还可以用方括号[]:
var s = 'test'; undefined s.charAt(0) === s[0] true
方括号代替charAt()更加简洁,可读并且高效。
也可以用数组的方法应用在字符串上面:
Array.prototype.join.call(s,",")
"t,e,s,t"
注意:字符串是不可变值,当做数组看待时候,只读。所以,push,sort,reverse,splice等在字符串上面是无效的。而且尝试用会报错。