数据类型【堆栈】【传参区别】【微重点】

数据类型

我们都知道,数据类型分为简单数据类型(string,number,boolean,以及两种空【undefined,null】),和复杂数据类型(object,array等)

简单数据类型(值类型)

细说简单数据类型的话,我们要记住一个特殊的情况,那就是null,这个值类型,如果使用typeof()检测一下的话,他的类型是对象object,这个是一个bug,并且没有去修复。那么你可能要问了,那他的使用场景呢?eg:如果我们要创建一个对象,但是又没想好,给他写哪些属性值的时候,那就直接让一个对象名等于null。

聊完特殊情况那么看看简单数据类型是如何存储的吧:

在此之前我们得先知道栈和堆的概念;栈和堆都是内存空间,但是存储的东西是有差别的。

  1. 栈里面存的是简单数据类型的值,以及复杂数据类型的地址值;

  2. 堆里面存的是复杂数据类型的值。

1> 接下来看简单数据类型如何存储的。

假如说我们定义一个变量num,存储值为:123 ,也就是var num = 123;,我们上面说到,栈是存储简单数据类型的…那么看如下图演示…(看图更加形象)

在这里插入图片描述
上图刚刚保存的太快,忘了写画步骤了,在这里补上…

  1. 先声明num
  2. 在栈空间开辟值为123的空间
  3. 变量num指向栈中的123空间
简单数据类型如何传参

我们给设置个场景:

		function fn(a) {
                a++;
                alert(a);              // 值为多少?
        }
        var x = 10;
        fn(x);
        alert(x);                    // 值为多少?

我们把这段代码拿到我们的绘图软件中分析。
在这里插入图片描述
过程解释:

最上面是一个函数我们不用看,因为函数不调用是不会执行的。那么往下分析var x = 10 ;那么就在栈中开辟一个空间储存10,然后x指向10,下面是调用了fn(x),由于x的值我们是知道的,相当于给函数传了一个实参为10的数字,那么此时形参a也就等于10,那么在栈中也就开辟了一个新的空间存储a的值,很显然函数内部让a自增了,那么他的结果也就重新改变了一次,为:a=10+1=11,此时已经算出fn(x)的值为11;接下来就是最后一行代码alert(x),由于x的指向是10并没有发生改变,因此输出结果为10;

第一个值显然为:11 (此时是调用的函数,值是看a的值)
第二个值显然为:10 (此时是输出原来的x指向,是不变的,依旧为10)


复杂数据类型

上面我们从简单数据类型是怎么在栈中存储的,以及怎么传参访问,那么我们复杂数据类型也有自己存储机制,以及如何传参…

怎么存储:
复杂数据类型的存储用到了栈和堆,但是结果是存储在堆中的,那么栈中存什么呢?存堆中值的地址,这个地址是十六进制数码,谁指向十六进制数码呢?那就是复杂数据类型的变量名。也就是说我们创建了一个 var arr = ['a', 'b','c'];我们想访问数组,那么就分为三个步骤,arr 指向栈中的十六进制地址,地址再指向堆中的复杂数据类型的
图示:
在这里插入图片描述
首先声明一个复杂类型变量arr,然后再栈中开辟一个空间存储堆中值的地址,最后变量指向地址,地址指向值.

此时和普通数据类型相比,一个存在堆中,一个存在栈中,并且存在堆中的复杂数据类型比简单数据类型的存储多了一步(在栈中开辟一个空间地址)…

那么复杂数据类型的传参怎么分析呢?
以以下代码为例:

	<script>
        function Person(name) {
            this.name = name;
        }

        function f1(x) {
            alert(x.name); // 此时输出的是什么?       靓仔
            x.name = '旺仔';
            alert(x.name); // 此时输出的是?           靓仔
        }
        var p = new Person('靓仔');
        alert(p.name); // 此时输出的是?               旺仔
        f1(p);
        alert(p.name); //  此时输出的是?              旺仔
    </script>

在这里插入图片描述

代码分析:

把复杂类型作为参数传递到函数中的时候,想当于让他赋值给了形参,但是赋值的并不是值,而是地址,想当于在栈中重新开辟了一个一模一样的地址,让形参指向该地址,他们两个地址因为相同,因此都指向堆中的一个值。

下面我们分析代码:上面是一个构造函数和一个普通函数,老样子函数不调用也就不执行,我们先不看;继续往下走,下面是把构造函数new出来,并且给它传递了一个name参数为靓仔,那么此时堆中的情况就如上图3.所示,里面的name = ‘‘靓仔’’;那么继续往下走,此时输出了实例化的p.name那么显然此时的name 为 靓仔,继续往下看;调用了函数fn§,此时相当于调用了第二个函数,并且把new出来的对象作为实参传给了函数fn,那么此时f1中的形参x也就等于了对象p,此时给形参x在栈中开辟一个地址,很显然地址与之前的一样,既然地址一样,那么也就指向了同一个堆中的值;我们继续看函数体,此时调用了x.name很显然,既然指向的地址都一样,那么值也一样,我们也就可以得出,此时的x.name还是等于靓仔;接下来我们看到给形参更换了值为:x.name = "旺仔" ;此时看下图:
在这里插入图片描述
我们发现,此时堆中的值是彻底改变了,因为两个变量指向的都是一个值,通过任何一个改变,另外一个指向的值也就随着改变,这个与简单数据类型是不一样的、这一点可以作为区分点。

那么从此刻开始不管调佣x.name也好,还是p.name也好,值都为旺仔而不再是靓仔了.

输出结果为: 靓仔 靓仔 旺仔 旺仔


tips: 看清楚指向,开辟好空间。切记形参也是一个变量,在传参的时候也要给他开辟空间噢…

不断复盘,不断优秀,让自己成为镜子里想成为的那个人.关注三连,持续更新~~~
在这里插入图片描述

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值