数据类型之间的区别

117 阅读5分钟

数据类型之间的区别

数据类型分为两种

基础数据类型(简单数据类型)

引用数据类型(复杂数据类型)

存储

变量的数据存储地方是内存(栈内存、堆内存)

(1)基本数据类型的类型保存在栈区;

基本数据:string number undefined null boolean

(2)引用数据类型的数据要用到两个区域:在栈区保存的是一个地址信息,而在堆区保存着真正的数据,这个堆区的地址就在栈区中保存着。

var a = [10];
var b = 1;

赋值新.png

赋值操作

赋值运算符= 左边是变量(或者是常量) 右边复杂 是值 、是变量、是函数

1.右边是值

varName = value;

背后做的事有

1.检查等号左边的这个变量是否存在。如果不存在,是否允许创建这个变量。这一步没有问题了,再去看右边。

2.把右边的值找个地方存起来,此时就要根据右边的值是引用类型还是基本数据类型来决定如何去保存它了,如果是基本数据类 型,则直接保存在栈区;如果是引用类型,则先在堆区中保存数据,再把地址保存在栈区。

2.右边是变量

varName = var1;

它表示把等号右边的变量中保存的值赋值到等号左边的变量(或者是常量)中。是直接把栈区中的保存的内容进行赋值。

3.右边是函数调用

varName = 函数调用();

先把函数执行完成,再把函数的返回值保存在左边的变量中

总结赋值

基本数据类型:赋值以后,两个变量之间没有任何关系,相当于将我自己的某一个东西, 复制一份给你, 然后你的就是你的, 我的就是我的

引用数据类型:存在堆空间中 将堆空间地址存在栈空间

赋值传递的是栈空间中的地址值

声明a引用数据类型 将a赋值给b

相当于 a和b 共用一个地址 当a或b改编 会相互影响

但如果a 或者b 重新赋值了一个引用数据类型 地址就会改变

例子

var a = [1];
var b = a; // 注意这一句

赋值2xin.png

接下来通过下标给b赋值

var a = [1];
var b = a; 
b[1] = 10; // 把10保存在第二个元素中。
console.log(a)//[1,10]
console.log(b)//[1,10]

赋值3xin.png 再接下来,重新给b赋值

var a = [1];
var b = a; 
b[1] = 10; 
b = [10]; // 把数组保存在b中
console.log(a)//[1,10]
console.log(b)//[10]

b=[10] 的运行结果是:

(1)找个地方保存数组,由于数组是引用数据类型,所以需要栈区和堆区一起配合。

(2)把地址保存在变量b中。从a,b不再指向同一个数组,它们从此是路人

赋值4xin.png

比较

基本数据类型: 直接存放到栈内存

就是栈内存 值 的比较

引用数据类型: 比较的时候 比较的是 存在栈内存内的存储地址

[] 不等[] 因为是两个数组 两个地址值

参数传递(比较复杂)

本质:在函数的调用过程中,存在传值的过程 具体来说,是实参的值传给形参

基本数据类型: 将值拷贝一份传递给形参, 在函数内修改不会影响外界

引用数据类型: 将存储地址赋值给形参, 在函数内修改会影响外界

function fn(a){
//形参a
//把实参的值 赋值给形参
    var a = b
    //形参就是函数内部的局部变量
    //实参传递给形参是给这个局部变量传值
}
var b = 100
f(b)//实参

•函数的形参就是函数内部定义的局部变量。•实参传递给形参的过程就是一个赋值过程。•函数调用结束后,局部变量会被回收

例子(引用数据类型)

var a = [1];
function f(a){
    //实参a 赋值给了 局部变量a  共用同一个地址值
    a[1] = 10
    //形参a重新赋值数组 有了新地址 跟全局的a 不共用一个地址了
    a = [10]
}
f(a);
console.info(a)//[1,10]

分析步骤 初始情况下:

在调用f(a)时,相当于是做了一次赋值操作:把全局变量a的值赋值给 局部变量a(赋值的内容是栈中的内容),结果是它们指一个数组。

传参1新.png 下面执行函数体中的第一句:

传参2xin.png 下面执行函数体中的第二句

传参3xin.png 最后一步:

函数调用结束,释放函数中的变量及对应的空间。

传参4xin.png

有形参函数和无形参函数

//有形参实参*****************
var a = [1];
    function f(a){
	    //实参a 赋值给了 局部变量a  共用同一个地址值
      a[1] = 10
      //形参a重新赋值数组 有了新地址 跟全局的a 不共用一个地址了
      a = [10]
    }
    f(a);
    console.info(a)//[1,10]


//没有形参实参*********************
    var a = [1];
    function f(){
	  //没有形参 a[1]=10 本作用域没有声明 a[1]
      a[1] = 10
      //a = [10] 也没有定义 向上查找 全局定义了a  
      //a 赋值一个数组 在堆空间开辟了新地址 存到栈空间
      a = [10]
    }
    f();
    console.info(a)//[10]