Javascript-僞數組

什麼是僞數組

僞數組是一個含有length屬性的json對象javascript

例如:java

{
    0: 1,
    1: 2,
    length: 2
}

常見的僞數組

arguments、NodeList、HTMLCollection、Jquery對象...git

僞數據如何轉成標準數組

使用Array.slice github

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);
        }
    }
}
相關文章
相關標籤/搜索