JS深拷贝 浅拷贝、CSS垂直水平居中

深拷贝与浅拷贝

浅拷贝:

浅拷贝,通俗来说,就是把一个对象obj1的属性值直接拷贝给另一个对象。不管这个值是普通的数据类型,还是引用类型。

实现方法:

1.使用Object.assign方法

javascript 复制代码
let obj1 = {...};
let obj2 = Object.assign({},obj1);

2.使用扩展运算符

javascript 复制代码
let obj1 = { ... };
let obj2 = { ...obj1 };

3.手写拷贝函数

javascript 复制代码
function getShallowClone(obj1){
    if(!obj1 || typeof obj1 !== 'object'){
        return ;
    } //传入的参数必须是对象
    
    let obj2 = Array.isArray(obj1) ? [] : {};
    //判断传入的是数组还是对象,确定拷贝副本的数据类型

    for(let key in obj1){
    
        if(obj1.hasOwnProperty(key)){
        
            obj2[key] = obj1[key]; //遍历obj1的key,并且把value直接赋值给Obj2        
        }

    }
    
    return obj2; //返回副本
}

拷贝对象的属性与源属性共享相同的引用。当更改源对象或拷贝的副本时,可能导致对应的对象也发生更改。

如果对象obj1是obj2的浅拷贝,obj1!==obj2成立。两个对象的属性有相同的名称且顺序相同、属性值相等、原型链相等。

对拷贝的副本的顶层属性的重新赋值不会影响源对象;对拷贝副本的嵌套对象的重新赋值会影响源对象(也就是说,拷贝副本和源对象有相同的引用,如果是修改拷贝副本顶层属性,相当于把顶层属性存储的内容直接改变,因此不会影响源对象。但如果是对嵌套对象,也就是对引用的内容进行操作,由于两者的引用相同,这种修改会影响到源对象)。

在JS中,标准的内置对象赋值操作都是浅拷贝。比如数组的concat方法、slice方法、from方法、Object.assign方法。

JS函数传参就是浅拷贝。

深拷贝

指拷贝副本和源对象的属性不共享相同的引用。当更改源对象或拷贝副本时,不会导致对方数据的变化。

对于两个对象obj1和obj2,如果obj2是obj1的深拷贝,则:obj1和obj2的属性具有相同的名称和相同的顺序、他们的属性值和原型链是结构等价的。obj1!==obj2成立。

深拷贝的实现:

1.通过JSON.stringify和JSON.parse

javascript 复制代码
let obj2 = JSON.parse(JSON.stringify(obj1));

2.手写深拷贝函数

javascript 复制代码
function getDeepClone(obj1){
    if(obj1 || typeof obj1 !== 'object'){
        return ;
    }

    let obj2 = Array.isArray(obj1) ? [] : {};

    for(let key in obj1){
        if(obj1.hasOwnProperty(key)){
            obj2[key] = typeof obj1[key] === 'object' ? getDeepClone(obj1[key]) : obj1[key];
        }
    }

    return obj2;
}

CSS实现垂直水平居中

以下方法一般也可以应用在水平或垂直居中中,只要单独设置水平的居中,和垂直的居中就可以了,思路都是一样的。

1.定位+负边距

思路:外部父元素是定位元素relative或absolute,内部子元素的定位是absolute,子元素相对父元素定位,偏移top 50%、left 50%,再通过margin-top: 负的子元素高的一半、margin-left:负的子元素宽的一半,把子元素调整到中间。

适用场景:需要知道子元素的宽和高。

代码:

html 复制代码
<body>
    <div class="outer">
        <div class="inner">

        </div>
    </div>

    <style>
        .outer{
            position: absolute;
            height: 800px;
            width: 1200px;
            background-color: blueviolet;
        }
        .inner{
            position: absolute;
            left: 50%;
            top: 50%;
            width: 100px;
            margin-left: -50px;
            height: 200px;
            margin-top: -100px;
            background-color: aquamarine;
        }
    </style>
</body>

2.设置定位 + transform

思路:父元素设置定位,position是absolute或relative,子元素设置absolute,top 50% left 50%,通过transform移动到正中间。

代码:

html 复制代码
<body>
    <div class="outer">
        <div class="inner">

        </div>
    </div>

    <style>
        .outer{
            position: absolute;
            height: 800px;
            width: 1200px;
            background-color: blueviolet;
        }
        .inner{
            position: absolute;
            left: 50%;
            top: 50%;
            width: 100px;
            height: 200px;
            transform: translate(-50%, -50%);
            background-color: aquamarine;
        }
    </style>
</body>

3.设置 定位+ margin:auto

思路:父元素是定位元素absolute或relative,子元素的position设置为absolute,相对父元素定位,然后四个定位都是0,margin:auto。

代码:

html 复制代码
<body>
    <div class="outer">
        <div class="inner">

        </div>
    </div>

    <style>
        .outer{
            position: absolute;
            height: 800px;
            width: 1200px;
            background-color: blueviolet;
        }
        .inner{
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
            margin: auto;
            width: 100px;  
            height: 200px;
            background-color: aquamarine;
        }
    </style>
</body>

4.使用flex布局

思路:让外部父元素的display是flex,内部子元素成为flex item,然后设置子元素沿着主轴和副轴居中。

代码:

html 复制代码
<body>
    <div class="outer">
        <div class="inner">

        </div>
    </div>

    <style>
        .outer{
            display: flex;
            align-items: center;
            justify-content: center;
            height: 800px;
            width: 1200px;
            background-color: blueviolet;
        }
        .inner{
            width: 100px;  
            height: 200px;
            background-color: aquamarine;
        }
    </style>
</body>

5.设置display table-cell

思路:把外部父元素设置display:table-cell,以及vertical-align、text-align居中。内部子元素设置display:inline-block。

代码:

javascript 复制代码
<body>
    <div class="outer">
        <div class="inner">

        </div>
    </div>

    <style>
        .outer{
            display: table-cell;
            vertical-align: middle;
            text-align: center;
            height: 800px;
            width: 1200px;
            background-color: blueviolet;
        }
        .inner{
            display: inline-block;
            width: 100px;  
            height: 200px;
            background-color: aquamarine;
        }
    </style>
</body>
相关推荐
小徐_23331 小时前
Wot UI 2.2.0 发布:Button 新增 subtle,VideoPreview 预览体验继续增强
前端·微信小程序·uni-app
山河木马3 小时前
矩阵专题3-怎么创建投影矩阵(uProjectionMatrix)
javascript·webgl·计算机图形学
天蓝色的鱼鱼4 小时前
关于 CSS 你可能不知道的属性,但关键时刻很有用
前端·css
泯泷4 小时前
第 2 篇:设计第一套字节码:Opcode、Instruction 与 Constant Pool
前端·javascript·安全
妙码生花4 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(十五):优化细节、网络请求封装
前端·后端·ai编程
泯泷5 小时前
第 1 篇:从 1 + 2 开始:亲手写出第一台 JSVM
前端·javascript·安全
团团崽_七分甜5 小时前
Spring Boot 核心知识点总结
前端
lichenyang4535 小时前
从一个按钮开始,理解 ASCF 框架到底在做什么
前端
古夕5 小时前
第三方 SSO 接入实践:redirect_uri 编码、回调一致性与跨项目联调
前端·vue.js