深浅拷贝的学习

学习 从零实现jQuery的extend

浅拷贝的使用场景

  1. Object.assign
  2. … 扩展运算符
  3. Array.prototype.slice.call

浅拷贝的实现

其原理就是 拷贝一个对象的属性到另一个对象中

var shallowCopy = function (obj) {
    if (typeof obj !== 'Object') return 
    // 根据obj的类型创建新的newObj
    var newObj = obj instanceof Array ? [] : {}
    // 遍历obj的属性
    for (var key in newObj) {
        if (obj.hasOwnProperty(key) {
        	newObj[key] = obj[key]
        })
    }
	return newObj
}

深拷贝的实现

拷贝的时候判断一下属性值的类型,如果是对象,递归调用深拷贝函数即可

var deepCopy = function (obj) {
    if (typeof obj !== 'Object') return
    var newObj = obj instanceof Array ? [] : {}
    for (var key in newObj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]
        }
    }
}

学习jquery中的extend

第一步,我们根据上面浅显的浅拷贝实现来写一下extend方法

function extend () {
    var copy, options, name
    var length = arguments.length
    var target = arguments[0]
    for (var i = 1; i < length; i++) {
        options = arguments[i]
        if (options !== null) {
            for (name in options) {
                copy = options[name]
                if (copy !== undefined) {
                    target[name] = copy
                }
            }
        }
    }
    return target
}
      var obj1 = {
          a: 1,
          b: { b1: 1, b2: 2 }
      };
      var obj2 = {
          b: { b1: 3, b3: 4 },
          c: 3
      };
      var obj3 = {
          d: 4
      }
      console.log(extend(obj1, obj2, obj3))

[外链图片转存失败(img-PDVXFDnt-1567236834468)(D:\2019.5月秋招准备\面试题\深浅拷贝\1.png)]

进行深拷贝

function deepExtend () {
    var copy, options, name, src
    // 默认值为false
    var deep = false
    var length = arguments.length
    // 记录要复制的对象的下标
    var i = 1
    var target = arguments[0] || {}
    // 如果第一个参数是个布尔值
    if (typeof target === 'boolean') {
        deep = target
        target = arguments[i] || {}
        i++
    }
    // 只有对象才可以进行复制,所以要判断一下
    if (typeof target !== 'Object') {
        target = {}
    }
    for (; i < length; i++) {
       	options = arguments[i]
        for (name in options) {
            src = target[name]
			copy = options[name]
           	
            // 如果对象里面还是对象,并且要求深拷贝的话
            if (deep && copy && typeof copy === 'object') {
                target[name] = deepExtend(deep, src, copy)
            } else {
                target[name] = copy   
            }
            
        }
    }
    return target
}

// 测试例子
      var obj1 = {
          a: 1,
          b: { b1: 1, b2: 2 }
      };

      var obj2 = {
          b: { b1: 3, b3: 4 },
          c: 3
      };

      var obj3 = {
          d: 4
      }
      console.log(deepExtend(true, obj1, obj2, obj3));

在这里插入图片描述
这样就实现了,当对象中存在的对象时,也能正确的遍历

对以上进行一下优化

其实就是把重复的方法提取出来,比如判断某元素是否是对象

let isObject  = (source) => {
    return Object.prototype.toString.call(source) === '[object Object]'
}
let deepExtend = () => {
    let copy, name, options, target, src
    let deep = false
    let i = 1
    let length = arguments.length
    target = arguments[0] || {}
    if (typeof target === 'boolean') {
        deep = target
        target = arguments[i] || {}
        i++
    }
    if (!isObject(target)) {
        target = {}
    }
    for (; i < length; i++) {
        options = arguments[i]
        if (options !== null) {
            for (name in options) {
                src = target[name]
                copy = options[name]
                if (deep && copy && isObject(copy)) {
                    target[name] = deepExtend(deep, src, copy)
                } else {
                    target[name] = copy
                }
            }
        }
	}
    return target
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值