RegExp

正则大全

数据类型

现有的数据类型有八种, 分别是

  • ES5 的 Number、String、Boolean、Null、Undefined、Object
  • ES6 的 Symbol
  • Google 67 后的 bigInt, 指的是安全存储、操作大整数

延伸: 深浅拷贝

浅拷贝

浅拷贝的意思就是指复制引用, 而未复制真正的值, 可使用 Object.assign()Array.concat()= 等进行浅拷贝

对于目标对象第一层为基本数据类型的数据直接赋值, 即「传值」; 而对于目标对象第一层为引用数据类型的数据, 就直接赋存于栈内存中的对内存地址, 即「传址」, 并没有开辟新的栈, 也就是复制的结果是两个对象指向同一个地址, 修改其中一个, 另一个也会改变

1
2
3
4
5
const originArr = { a: 'a', b: 'b', c: [1, 2, 3], d: { dd: 'dd' } };
const clonedArr = originArr;
originArr.a = { aa: 'aa' };
console.log(originArr); // { a: { aa: 'aa', b: 'b', c: [1, 2, 3], d: { dd: 'dd' }}};
console.log(clonedArr); // { a: { aa: 'aa', b: 'b', c: [1, 2, 3], d: { dd: 'dd' }}};

上述代码利用了 = 赋值操作符实现了一个浅拷贝, 可以很清楚的看到, 随着 originArr 的变化, clonedArr 也随着发生了变化

深拷贝

深拷贝就是对目标的完全拷贝, 不像浅拷贝那样只是复制了一层引用, 就连值也复制了, 只要使用了深拷贝, 两者没有任何关联 (两者指向不同的内存地址)

开辟新的栈, 两个对象对应两个不同的地址, 修改一个对象的属性, 不会改变另一个对象的属性

目前实现深拷贝的方法, 主要有两种

  1. 利用 JSON.parse(JSON.stringify(对象))
    • JSON.parse() 将一个 JSON 字符串转成一个 JS 值或对象
    • JSON.stringify() 将一个 JS 值转成一个 JSON 字符串
      1
      2
      3
      4
      5
      const originArr = { a: 'a', b: 'b', c: [1, 2, 3], d: { dd: 'dd' } };
      const clonedArr = JSON.parse(JSON.stringify(originArr));
      originArr.a = { aa: 'aa' };
      console.log(originArr); // { a: { aa: 'aa', b: 'b', c: [1, 2, 3], d: { dd: 'dd' }}};
      console.log(clonedArr); // { a: 'a', b: 'b', c: [1, 2, 3], d: { dd: 'dd' } };
    • 这个方法确实很方便, 但是只适用于一些简单的情况, 当其中的参数有 undefinedfunctionsymbol 会在转换过程中被忽略; 当对象中含有函数时, 就不能用这个方法来进行深拷贝
      1
      2
      3
      4
      5
      6
      7
      8
      9
      const originObj = {
      name: 'aa',
      sayHello: function () {
      console.log('Hello World');
      }
      }
      console.log(originObj); // { name: 'aa', sayHello: ƒ }
      const cloneObj = JSON.parse(JSON.stringify(originObj));
      console.log(cloneObj); // { name: 'aa' }
  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
      function deepClone(source) {
      // 判断复制的目标是数组还是对象
      const targetObj = source.constructor === Array ? [] : {};
      for (let keys in source) {
      if (source.hasOwnProperty(keys)) {
      // 如果值是对象, 就递归一下
      if (source[keys] && typeof source[keys] === 'object') {
      targetObj[keys] = source[keys].constructor === Array ? [] : {};
      targetObj[key] = deepClone(source[keys]);
      // 如果不是, 直接赋值
      } else {
      targetObj[keys] = source[keys];
      }
      }
      }
      return targetObj;
      }
      // ES6 实现
      deepClone: source => {
      let clone = Object.assign({}, source);
      Object.keys(clone).forEach(key => (clone[key] = typeof source[key] === 'object'
      ? deepClone(cource[key])
      : cource[key]));
      return clone;
      }

      JS 中数组和对象自带的拷贝方法都是“首层浅拷贝”, 即只深拷贝第一层, 没有深层深拷贝的能力