【进阶】深拷贝

作者: woow_wu7 | 来源:发表于2019-03-05 22:38 被阅读5次

    目录:
    1 深拷贝
    2 浅拷贝
    3 文字超出两行显示省略号
    4 height: 100%如何才能生效
    5 path不包括 ?和 #

    前言

    (1) 基本数据类型,引用数据类型

    基本数据类型:number, string, boolean, null, undefined, symbol
    引用数据类型:object, array, function

    • 区别:
      基本类型没有属性和方法,保存在栈区。
      引用类型有属性和方法,保存在栈区和堆区。
      引用类型按引用访问
      引用类型: 栈区保存变量标识符和指针,指针指向堆内存中该对象,保存在变量中的是对象在堆内存中的地址
    • 浅拷贝只能用于对象中只包含基本类型的数据,修改其中一个的属性后,相互不影响,当对象中仍然包含对象类型的数据时,则是引用关系,修改会相互影响,所以这种情况需要用到深拷贝
    const arr = [1];
    const obj = { a: 1 };
    const newArr = arr;   
    const newObj = obj; ------------------ 变量 newObj 和 obj 保存的都是指向同一对象堆内存的指针(引用), 是指针
    arr[0] = 2;
    obj.a = 2;
    console.log(arr, newArr, obj, newObj);  // [2] [2] {a: 2} {a: 2}
    
    
    
    
    
    
    var a = {}; // a保存了一个空对象的实例
    var b = a;  // a和b都指向了这个空对象
    a.name = 'jozo';
    console.log(a.name); // 'jozo'
    console.log(b.name); // 'jozo'
    b.age = 22;
    console.log(b.age);// 22
    console.log(a.age);// 22
    console.log(a == b);// true
    
    QQ截图20190219105922.png

    深拷贝方法一

    JSON.parse(JSON.string(obj))

    • 缺点: 只能拷贝对象和数组,无法拷贝函数,无法拷贝原型链上的属性和方法(Date, RegExp, Error等)
     const ojbComplex = {
          name: 'wu',
          age: 20,
          address: {
            city: 'chongqing',
            district: 'yubei',
            town: 'jiazhou',
            detail: ['chognqing', 'yubei', 'jiazhou']
          },
          bwh: [20, 30, 40, {l: 20, w: 30, h: 40}],
          fn: function(){},
          date: new Date(),
          err: new Error(),
          reg: new RegExp(),
          null: null,
          undefined: undefined,
        }
        const deepClone = JSON.parse(JSON.stringify(ojbComplex));
        console.log(ojbComplex, 'ojbComplex')
        console.log(deepClone, 'deepClone');
    
    
    缺点:
    不能拷贝fn, date, err, reg
    
    QQ截图20190219111653.png

    深拷贝方法二

    for...in 循坏递归

    
    function deepClone(obj) {
      let objClone = Array.isArray(obj) ? [] : {};
      if (obj && typeof obj === 'object') {
        for(let key in obj) {
            if ( obj.hasOwnProperty(key) ) {
              if ( obj[key] && typeof obj[key] === 'object') {
                objClone[key] = deepClone(obj[key]);   --------- 递归调用,deepClone()函数的返回值是objClone
              } else {
                objClone[key] = obj[key];
              }
             }
            }
          }
      return objClone;
    }
    
    
    
    
        const params = {
          name: 'wang',
          address: {
            city: ['china', 'choing'],
            district: {
              town: 'jiazhou'
            }
          }
        };
        const b = deepClone(params);
        console.log(b)
    
    
    缺点: 和JSON.parse(JSON.stringify(ojb)) 一样, 不能拷贝 fn, date, reg,err
    

    https://zhuanlan.zhihu.com/p/41699218 lodash deepclone 源码分析
    https://www.jianshu.com/p/c651aeabf582
    https://www.jianshu.com/p/b08bc61714c7
    https://segmentfault.com/a/1190000015455662

    浅拷贝

    • slice()
    • concat()
    • Object.assign(target, ...sources)
    • {...obj} 和 [...arr]
    • 循坏push
    浅拷贝
    
    const a = [1, {name: 'wang'}];
    const b = [...a];
    a[0] = 2;
    a[1].name = 'li';
    console.log(b)   
    b // [1, { name: 'li' } ]
    
    
    
    
    const a = [1,2,3];
    const b = a.concat();
    const c = a.slice();
    a[0] = 111111;
    console.log(b);
    console.log(c);
    b // [1,2,3]
    c // [1,2,3]
    
    
    
    
    const a = { name: 'wang' };
    const b = Object.assign({}, a);
    a.name = 'li';
    console.log(b);
    b  // { name: 'wang'}
    

    文字超出两行显示省略号

    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    
    
    
    英文单词时:
    word-wrap:break-word; --- word-wrap: 属性允许长单词或URL地址换行到下一行, break-word: 单词内换行
    word-break:break-all;  ------------------ word-break: 规定自动换行的处理方式,break-all: 允许单词内换行
    
    
    
    总结:
    word-wrap: break-word;  ------------ 整个单词换行
    word-break: break-all;   ------------ 单词内换行
    white-space: nowrap;     ------------ 单词不换行
    

    文字超出单行不换行,显示省略号

    .word {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;   --------------- 单词不换行
    
      word-wrap: break-word; --------------- 整个单词换行
      word-break: break-all; --------------- 单词内换行 (单行显示省略号,后面两个属性可以不加)
    }
    

    https://www.cnblogs.com/ldlx-mars/p/6972734.html

    height: 100%如何才能生效?

    • 原理:height: 100%是根据父元素作为参照的,如果父元素的高度是一个缺省值,即height:auto,则子元素设置height: 100%将不能达到效果。
    • 结论:普通文档流中的元素,百分比高度值要想起作用,其父级必须有一个可以生效的高度值!
    让div充满整个屏幕
    
    
    方法1
    解析:当html和body都设置了height: 100%时,子元素的height:100%就会生效
    <!DOCTYPE html>
    <html>
    <head>
      <style>
        html, body {  
          height: 100%;
          width: 100%;
          background: red;
          padding: 0;
          margin: 0;
        }
        .a {
          height: 100%;
          width: 100%;
          background: black;
        }
      </style>
    </head>
    <body>
      <div class="a">
        <div class="b">居中</div>
      </div>
    </body>
    </html>
    
    
    
    
    
    方法2
    解析:使用绝对定位,当所有父节点都没有设置定位信息时,是根据html来定位的
    <!DOCTYPE html>
    <html>
    <head>
      <style>
        * {
          margin: 0;
          padding: 0;
        }
        .a {
          height: 100%;
          width: 100%;
          position: absolute;
          background: yellow;
        }
      </style>
    </head>
    <body>
      <div class="a">
        <div class="b">居中</div>
      </div>
    </body>
    </html>
    

    相关文章

      网友评论

        本文标题:【进阶】深拷贝

        本文链接:https://www.haomeiwen.com/subject/cbcxyqtx.html