【Mockjs】源码分析1-Util.extend

简介:Mock是一个前端常用的接口模拟器。本专栏是对mockjs源码进行细致的分析。
概述:本次的内容是Util工具类的extend函数,通过迭代+深拷贝的方式增强构造函数
github:https://github.com/nuysoft/Mock
  1. 作用分析

util.extend存在于/src/mock/util.js,接收>=两个参数,分别为待增强对象和增强对象s

// 构造函数
function ext() {
    this.name = {
        na: '123'
    }
}
// ext实例
var te = new ext()

console.log(te)
// ext { name: { na: '123' } }

// 增强对象
var high = { cd: 1, ag: 2 }

// 增强构造函数
Util.extend(te, high)

console.log(te)
// ext { name: { na: '123' }, cd: 1, ag: 2 }
  1. 源码分析

2.1 初始化部分

    var target = arguments[0] || {},
        i = 1,
        length = arguments.length,
        // options, name, src, copy, clone
        options, name, src, copy
  • target存储的是待增强对象

  • i暂存1,表示第一个增强对象

  • length表示参数数量

  • options、name、src、copy占位

2.2 迭代条件

    if (length === 1) {
        target = this
        i = 0
    }

当迭代到最后,参数中只剩下了需增强对象,而增强对象已经迭代完毕,则将target指向this,配合for条件终止迭代,逆向进行增强

2.3 迭代体

    for (; i < length; i++) {
        options = arguments[i]
        if (!options) continue

        for (name in options) {
            src = target[name]
            copy = options[name]

            if (target === copy) continue
            if (copy === undefined) continue

            if (Util.isArray(copy) || Util.isObject(copy)) {
                if (Util.isArray(copy)) clone = src && Util.isArray(src) ? src : []
                if (Util.isObject(copy)) clone = src && Util.isObject(src) ? src : {}
           
                target[name] = Util.extend(clone, copy)
            } else {
                target[name] = copy
            }
        }
    }
  • i控制options依次取得增强对象

  • name遍历增强options的键

  • src存储源对象的键值

  • copy存储增强对象的键值

  • 判断copy是否为对象/数组,是否需要迭代

  • 不需要迭代的话,则将target[name]设置为copy,完成对象增强

2.4 返回值

    return target

直接返回target即可

  1. 实战案例

const Util = {}

/**
 * 判断是否为数组
 * @param obj
 * @returns {boolean}
 */
Util.isArray = obj => {
    return obj instanceof Array ? true : false
}

/**
 * 判断是否为对象
 * @param obj
 * @returns {boolean}
 */
Util.isObject = obj => {
    return obj instanceof Object ? true : false
}

/**
 * 增强构造函数
 * @returns {any|{}}
 */
Util.extend = function () {

    let target = arguments[0] || {}, i = 1
    const length = arguments.length
    let options, name, src, copy, clone

    if (length === 1) {
        target = this
        i = 0
    }

    for (; i < length; i++) {

        options = arguments[i]

        if (!options) continue

        for (name in options) {

            src = target[name]
            copy = options[name]

            if (target === copy) continue
            if (copy === undefined) continue

            if (Util.isArray(copy) || Util.isObject(copy)) {

                if (Util.isArray(copy))
                    clone = src && Util.isArray(src) ? src : []
                if (Util.isObject(copy))
                    clone = src && Util.isObject(src) ? src : {}

                target[name] = Util.extend(clone, copy)

            } else {

                target[name] = copy

            }
        }
    }

    return target

}
// 初始化构造函数
function Test() {
    this.info = {
        name: 'hh',
        age: 18
    }
}

console.log(Test)

// 增强对象1
const enhance1 = {
    nig: 'kk',
    kids: [
        'z3',
        'l4'
    ]
}

// 增强对象2
const enhance2 = {
    nig2: 'kk',
    kids2: [
        'z3',
        'l4'
    ]
}

// 增强构造函数
Util.extend(Test, enhance1, enhance2)

console.log(Test)

第一次的输出为:

[Function: Test]

第二次的输出为:

[Function: Test] {               
  nig: 'kk',                     
  kids: { '0': 'z3', '1': 'l4' },
  nig2: 'kk',                    
  kids2: { '0': 'z3', '1': 'l4' }
}      

成功增强了构造函数Test

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xxhls0208

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值