1.一个有趣的类数组案例
var obj = {
'2': 3,
'3': 4,
'length': 2,
'splice': Array.prototype.splice,
'push': Array.prototype.push
}
obj.push(1)
obj.push(2)
console.log(obj)
复制代码
为什么说是一个类数组的使用案例,我们先来了解下类数组的概念以及判断方式
类数组(ArrayLike): 一组数据,由数组来存,但是如果要对这组数据进行扩展,会影响到数组原型,ArrayLike的出现则提供了一个中间数据桥梁,ArrayLike有数组的特性, 但是对ArrayLike的扩展并不会影响到原生的数组。
devtools判断源码
/**
* @param {?Object} obj
* @return {boolean}
*/
function isArrayLike(obj) {
if (!obj || typeof obj !== 'object')
return false;
try {
if (typeof obj.splice === 'function') {
const len = obj.length;
return typeof len === 'number' && (len >>> 0 === len && (len > 0 || 1 / len > 0));
}
} catch (e) {
}
return false;
}
复制代码
从源码中我们可以了解到,一个object类型,具有splice函数方法,且有一个正整数length作为属性,就可以判定为arraylike,可以使用数组的函数方法。
上面案例输出的答案是:Object(4) [empty × 2, 1, 2, splice: ƒ, push: ƒ]
原因:obj执行push的时候,是会根据length来判断追加的下标,当前length为2,那么push的数组下标从2开始,因此,当执行push(1),数组下标为2的地方值为1,push(2),类数组下标为3的地方值为2。数组本身0,1两个下标内没有值,因此类数组内容是[undefined,undefinded,1,2],输出结果就是稀疏数组Object(4) [empty × 2, 1, 2, splice: ƒ, push: ƒ]。
如果将length改为0
var obj = {
'2': 3,
'3': 4,
'length': 0,
'splice': Array.prototype.splice,
'push': Array.prototype.push
}
obj.push(1)
obj.push(2)
console.log(obj)
//Object(2) [1, 2, 2: 3, 3: 4, splice: ƒ, push: ƒ]
复制代码