第五节:补充引用类型赋值、浅拷贝、深拷贝、判断中的隐式转化

一. 引用类型赋值

1. 原理

(1). js中对象和数组都是引用类型。

(2). 内存分为两个区域,栈区域 和 堆区域。

(3). 引用类型,在栈区域中存放的堆的二进制地址,这个地址指向 堆区域中的实际值。

(4). 将一个对象A赋值给另一个对象B,实际上是将A的地址赋值给了B,A和B共同指向同一个对象区域,所以改了B中的属性,A中的也改了。

2. 代码实战

<script type="text/javascript">
            //js中数组和对象都是引用类型

            var user1 = { name: 'ypf1', age: 10, child: { cname: 'ep1' } };
            var user2 = user1;
            
            user2.name='ypf2';
            user2.child.cname='ep2';
            
            console.log(user1.name);          //ypf2
            console.log(user1.child.cname);   //ep2
            
            
</script>

剖析: 

二. 浅拷贝和深拷贝

1. 浅拷贝

(1). 说明

  浅拷贝只会将对象的各个属性进行依次复制,并不会进行递归复制子对象。 所以赋值给user2中的child属性,复制的还是一个地址,所以改了cname,全改。

(2). 方案1

             var user1 = { name: 'ypf1', age: 10, child: { cname: 'ep1' } };

             //浅拷贝-方案1
              {
                var user2 = Object.assign({}, user1);
                user2.name = 'ypf2';
                // 对象中的对象,指向的还是地址,浅拷贝,拷贝过去的也是地址,改1个,就都改了
                user2.child.cname = 'ep2';

                console.log(user1.name);          //ypf1
                console.log(user1.child.cname);   //ep2
             }

(3). 方案2

  引用: <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>

            var user1 = { name: 'ypf1', age: 10, child: { cname: 'ep1' } };
   
            // 浅拷贝-方案2
            {
                var user2 = _.clone(user1);
                user2.name = 'ypf2';
                // 对象中的对象,指向的还是地址,浅拷贝,拷贝过去的也是地址,改1个,就都改了
                user2.child.cname = 'ep2';
                
                console.log(user1.name);          //ypf1
                console.log(user1.child.cname);   //ep2
            }

2. 深拷贝

(1). 说明

  深拷贝则不同,它不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深拷贝的方法递归复制到新对象上。所以user2对象中cname属性直接copy了内容,user1和user2中修改任何内容,相互不影响。

(2). 方案1

            var user1 = { name: 'ypf1', age: 10, child: { cname: 'ep1' } };
            // 深拷贝-方案1
            {
                var user2 = JSON.parse(JSON.stringify(user1));
                user2.name = 'ypf2';
                // 深拷贝,对象中的对象也全部copy了
                user2.child.cname = 'ep2';
                
                console.log(user1.name);          //ypf1
                console.log(user1.child.cname);   //ep2
            }

(3). 方案2

  引用 <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>

            var user1 = { name: 'ypf1', age: 10, child: { cname: 'ep1' } };
            // 浅拷贝-方案2
            {
                var user2 = _.cloneDeep(user1);
                user2.name = 'ypf2';
                // 对象中的对象,指向的还是地址,浅拷贝,拷贝过去的也是地址,改1个,就都改了
                user2.child.cname = 'ep2';
                
                console.log(user1.name);          //ypf1
                console.log(user1.child.cname);   //ep2
            }

三. 判断中的隐式转化

逻辑判断时, 可以转化的情况下, 会隐式的自动将一个string类型成一个number类型再来进行判断(隐式转化)
    <script type="text/javascript">
            const score = "100";
            // 逻辑判断时, 可以转化的情况下, 会隐式的自动将一个string类型成一个number类型再来进行判断(隐式转化)
            if (score > 90) {
                console.log(typeof score);     //转换完,后续的过程中,又变成string类型了
                console.log("优秀");
            }
    </script>

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 
原文地址:https://www.cnblogs.com/yaopengfei/p/15261698.html