/**
 * 模拟 JQuery 中的 extend 方法
 * @deep     设置是否进行深复制,可选
 * @target  目标数据
 * @args    多个数据对象
 */
function extend() {

    /* 参数列表 */
    // 操作类型
    let deep = false;
    // 目标数据
    let target = undefined;
    // 剩余参数
    let args = [];

    /* 参数修正 */
    // 检测第一个参数是否为布尔类型
    if (typeof arguments[0] === "boolean") {
        // 数据修正
        [deep, target, ...args] = [...arguments];
    } else {
        // 数据修正
        [target, ...args] = [...arguments];
    }

    // 检测是否为可迭代对象
    function isIter(data) {
        // 检测操作类型
        let type = Object.prototype.toString.call(data);
        // 判断是否为数组和对象
        return type === '[object Object]' || type === '[object Array]';
    }

    // 遍历对象集合
    for (let arg of args) {
        // 判断是否为可迭代对象,不是则直接跳过
        if(!isIter(arg)) continue;

        // 判断数据类型
        switch (Object.prototype.toString.call(arg)) {
            // 数组
            case '[object Array]':
                /* 适配 目标数据 与 拷贝数据 都是数组的情况 */
                // 检测目标是否为数组类型
                if (Array.isArray(target)) {
                    // 遍历数据数组
                    for (let item of arg) {
                        // 如果是深复制则递归执行并将返回值添加至结果数组
                        target.push(!deep && isIter(item) ? extend([], item) : item);
                    }
                    // 跳出 switch
                    break;
                }
            // 对象
            case '[object Object]':
                // 遍历数据对象
                for (let key in arg) {
                    /* 适配除 目标数据 与 拷贝数据 都是数组外的所有情况 */
                    // 检测操作类型,如果是深复制则递归执行并将返回值添加至结果对象
                    target[key] = !deep && isIter(arg[key]) ? extend({}, arg[key]) : arg[key];

                }
                // 跳出 switch
                break;
            // 其他类型
            default:
                // 跳出 switch
                break;
        }
    }
    // 返回结果变量
    return target;
}

winter
21 声望5 粉丝