对象的混合与克隆

对象的混合

两个对象,混合后产生一个新对象。

自定义实现:

var obj1 = {
  x: 1,
  y: 3,
  z: 5,
}

var obj2 = {
  x: 'abc',
  z: 'bcd',
  h: 'aaa',
}

/**
 * 混合对象,将对象 obj2 混合到 obj1,返回一个新对象。
 * 不会改变原对象
 */
function myMixin(obj1, obj2) {
  var newObj = {}

  // 复制 obj2的属性
  for (const prop in obj2) {
    newObj[prop] = obj2[prop]
  }

  // 找到 obj1中有 但是obj2中没有的属性
  for (const prop in obj1) {
    if (!(prop in obj2)) {
      newObj[prop] = obj1[prop]
    }
  }
  return newObj
}

var obj3 = myMixin(obj2, obj1)

console.log(obj3) // {x: "abc", y: 3, z: "bcd", h: "aaa"}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

使用 Object.assign() MDNopen in new window

var obj1 = {
  x: 1,
  y: 3,
  z: 5,
}

var obj2 = {
  x: 'abc',
  z: 'bcd',
  h: 'aaa',
}

/**
 * 混合对象,将对象 obj2 混合到 obj1,返回一个新对象。
 * 不会改变原对象
 */
function mixin(obj1, obj2) {
  return Object.assign({}, obj1, obj2)
}

var obj3 = mixin(obj2, obj1)

console.log(obj3) // {x: "abc", y: 3, z: "bcd", h: "aaa"}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

应用场景

// option 参数是一个对象,表示配置对象
function complicate(option) {
  // 如果没有传递,则使用默认值
  var defaultOprion = {
    a: 'default-a',
    b: 'default-b',
    c: 'default-c',
    d: 'default-d',
    e: 'default-e',
  }
  var opt = myPlugin.mixin(defaultOprion, option)

  return opt
}

// 没有传递参数对象
complicate()
//{a: "default-a", b: "default-b", c: "default-c", d: "default-d", e: "default-e"}

// 传递了参数对象
complicate({
  a: 'AAA',
  b: 'BBB',
})
// {a: "AAA", b: "BBB", c: "default-c", d: "default-d", e: "default-e"}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

对象克隆

把原来对象的属性遍历一遍,赋给一个新的对象。

/**
 * 克隆一个对象
 * @param {object} obj 要克隆的数据变量
 * @param {boolean} deep 是否深度克隆
 */
function objClone(obj, deep) {
  // 判断是不是数组
  if (Array.isArray(obj)) {
    if (deep) {
      // 深度克隆
      var newArr = []
      for (var i = 0; i < obj.length; i++) {
        newArr.push(this.clone(obj[i], deep))
      }
      return newArr
    } else {
      return obj.slice() // 复制数组
    }
  } // 判断是不是对象
  else if (typeof obj === 'object') {
    var newObj = {}
    for (var prop in obj) {
      if (deep) {
        // 深度克隆
        newObj[prop] = this.clone(obj[prop], deep)
      } else {
        newObj[prop] = obj[prop]
      }
    }
    return newObj
  } else {
    // 函数、原始类型
    return obj // 递归的终止条件
  }
}

var obj = {
  x: 1,
  y: 2,
  subObj: {
    a: 1,
    b: 2,
  },
}

var newObj = objClone(obj, true)

obj === newObj // false
newObj // {x: 1, y: 2, subObj: {a: 1, b: 2} }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49