共计 2357 个字符,预计需要花费 6 分钟才能阅读完成。
什么是伪数组
伪数组是一个含有 length 属性的 json 对象
例如:
{
0: 1,
1: 2,
length: 2
}
常见的伪数组
arguments、NodeList、HTMLCollection、Jquery 对象 …
伪数据如何转成标准数组
使用 Array.slice
function toArray() {
console.log(arguments instanceof Array) // false
arguments = Array.prototype.slice.call(arguments)
console.log(arguments instanceof Array) // true
return arguments
}
toArray(1,2,3) // [1, 2, 3]
Array.slice 源码解析(587 行)
function ArraySlice(start, end) {
CHECK_OBJECT_COERCIBLE(this, “Array.prototype.slice”);
var array = TO_OBJECT(this);
var len = TO_LENGTH(array.length); // 取数据 length
var start_i = TO_INTEGER(start); // 开始值转 Number
var end_i = len; // 结束值直接取 array 的 length
if (!IS_UNDEFINED(end)) end_i = TO_INTEGER(end); // 参数有 end 则使用 end
if (start_i < 0) {// 开始值为负数,重新计算值,从尾部往前推算
start_i += len;
if (start_i < 0) start_i = 0; // 负数的绝对值超过长度,开始值赋值为 0
} else {
if (start_i > len) start_i = len; // 开始值超过长度, 开始值赋值为 len
}
if (end_i < 0) {// 结束值为负数,重新计算值,从尾部往前推算
end_i += len;
if (end_i < 0) end_i = 0; // 负数的绝对值超过长度,结束值赋值为 0
} else {
if (end_i > len) end_i = len; // 开始值超过长度, 结束值赋值为 len
}
var result = ArraySpeciesCreate(array, MaxSimple(end_i – start_i, 0)); // 创建一个数组
if (end_i < start_i) return result; // 结束值小于开始值,那么直接返回空数组
if (UseSparseVariant(array, len, IS_ARRAY(array), end_i – start_i)) {// array 是数组
%NormalizeElements(array);
if (IS_ARRAY(result)) %NormalizeElements(result);
SparseSlice(array, start_i, end_i – start_i, len, result);
} else {// array 不是数组
SimpleSlice(array, start_i, end_i – start_i, len, result);
}
result.length = end_i – start_i; // 数组长度赋值
return result;
}
/*
* array 具体操作的数组
* start_i 开始位置
* del_count 需要处理的长度
* len 数组长度
* deleted_elements 利用浅拷贝,返回结果,对于 slice 来说,是选择的那部分数组,对于 splice 来说,是删除的那些数组
*/
function SparseSlice(array, start_i, del_count, len, deleted_elements) {
// Move deleted elements to a new array (the return value from splice).
var indices = %GetArrayKeys(array, start_i + del_count);
if (IS_NUMBER(indices)) {
var limit = indices;
for (var i = start_i; i < limit; ++i) {
var current = array[i];
if (!IS_UNDEFINED(current) || i in array) {
%CreateDataProperty(deleted_elements, i – start_i, current);
}
}
} else {
var length = indices.length;
for (var k = 0; k < length; ++k) {
var key = indices[k];
if (key >= start_i) {
var current = array[key];
if (!IS_UNDEFINED(current) || key in array) {
%CreateDataProperty(deleted_elements, key – start_i, current);
}
}
}
}
}
/*
* array 具体操作的数组
* start_i 开始位置
* del_count 需要处理的长度
* len 数组长度
* deleted_elements 利用浅拷贝,返回结果,对于 slice 来说,是选择的那部分数组,对于 splice 来说,是删除的那些数组
*/
function SimpleSlice(array, start_i, del_count, len, deleted_elements) {
for (var i = 0; i < del_count; i++) {
var index = start_i + i;
if (index in array) {
var current = array[index];
%CreateDataProperty(deleted_elements, i, current);
}
}
}