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

发布于:2025-08-12 ⋅ 阅读:(18) ⋅ 点赞:(0)

深拷贝与浅拷贝

浅拷贝:

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

实现方法:

1.使用Object.assign方法

let obj1 = {...};
let obj2 = Object.assign({},obj1);

2.使用扩展运算符

let obj1 = { ... };
let obj2 = { ...obj1 };

3.手写拷贝函数

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

let obj2 = JSON.parse(JSON.stringify(obj1));

2.手写深拷贝函数

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:负的子元素宽的一半,把子元素调整到中间。

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

代码:

<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移动到正中间。

代码:

<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。

代码:

<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,然后设置子元素沿着主轴和副轴居中。

代码:

<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。

代码:

<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>


网站公告

今日签到

点亮在社区的每一天
去签到