剩余参数

2023-03-26  本文已影响0人  欢西西西
// 剩余参数语法允许我们将一个不定数量的参数表示为一个数组

// let [first, ...lst] = arr; // 编译前



var _arr = arr,
    _arr2 = _toArray(_arr),
    first = _arr2[0],
    lst = _arr2.slice(1);


function _toArray(arr) {
    return _arrayWithHoles(arr) // 数组
        || _iterableToArray(arr) // 可迭代对象转数组
        || _unsupportedIterableToArray(arr) // 继续检查可以转成数组的对象
        || _nonIterableRest(); // 报错
}
function _nonIterableRest() {
    throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _unsupportedIterableToArray(o, minLen) {
    if (!o) return;
    if (typeof o === "string") return _arrayLikeToArray(o, minLen);

    var n = Object.prototype.toString.call(o).slice(8, -1); // [Object XXX] -> XXX

    if (n === "Object" && o.constructor)
        n = o.constructor.name;
    if (n === "Map" || n === "Set")
        return Array.from(o);
    // n是Object,用constructor.name来检查,表示检查的是Map和Set的polyfill创建的对象
    // ES6的Map和Set toString是 '[object Map]' 和 '[object Set]'


    // Int8Array/Uint8ClampedArray/Int16Array/Uint16Array/Int32Array/Uint32Array
    if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))
        return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
    if (len == null || len > arr.length) len = arr.length;
    for (var i = 0, arr2 = new Array(len); i < len; i++)
        arr2[i] = arr[i];
    return arr2;
}
function _iterableToArray(iter) {
    // 检查一个对象是否是可迭代的 
    if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null)
        return Array.from(iter);
    /**
     * iter[Symbol.iterator]属性值是一个函数,它返回一个迭代器对象 
     * let str = 'abc'; let iter = str[Symbol.iterator](); iter.next();
     * 可迭代的对象例如:字符串、数组、arguments、HTMLCollection 、生成器函数返回的迭代器对象、Map、Set。(WeakMap和WeakSet是不能迭代的)
     */
}
function _arrayWithHoles(arr) {
    if (Array.isArray(arr))
        return arr;
}
上一篇 下一篇

猜你喜欢

热点阅读