基本数据类型和引用数据类型 深拷贝,浅拷贝

一.js分两种数据类型

基本数据类型:Number、String、Boolean、Null、 Undefined、Symbol(ES6),这些类型可以直接操作保存在变量中的实际值。

引用数据类型:Object(在JS中除了基本数据类型以外的都是对象,数据是对象,函数是对象,正则表达式是对象)

二.内存存放的地址

 基本数据类型(存放在栈中)
 基本数据类型是指存放在栈中的简单数据段,数据大小确定,内存空间大小可以分配,它们是直   接按值存放的,所以可以直接按值访问

引用数据类型(存放在堆内存中的对象,每个空间大小不一样,要根据情况进行特定的配置)(这里要理解的一点就是,复制对象时并不会在堆内存中新生成一个一模一样的对象,只是多了一个保存指向这个对象指针的变量罢了)。多了一个指针

 简单地理解就是:复杂的数据类型,会在栈中保存一个地址,将数据保存在堆中以Object,需要使用的时候就会将指针,指向

三. 函数进行传参的问题,存放的形式,函数进行传参,相当于声明了一个变量,属于函数函数内部的局部变量。

题1

var a = [1];var b = a;b = [10]console.info(a)console.info(b)

解析:栈中有a变量  指针,地址,  代码执行到第二行,把a的值赋值给了b, a和b具有同样的地址,指向的堆都是[1]  , 代码执行到第三行,b=[10],又开辟了新的地址 这个地址指向堆中的[10] a任然用它的地址指向堆中的[1]

 题2:

var a = [1];var b = a;b[1] = 10console.info(a)console.info(b)

解析: 栈中有a的地址,堆中数值[1],把a的值赋值给b,b复制的是a的地址 指向的都是a中的堆[1],

因为地址相同,在数值中添加10,所有打印出结果[1,10]

题3:

var a = [1];function f(a){    a = [10]}f(a);console.info(a)

解析: 栈中有地址a的地址,堆中有值[1], 局部变量a复制了地址指向[1],a=[10],局部变量生成一个新的地址指向[10],访问的全局的所有打印出来的结果是[1];

题四:

var a = 1;function f(a){    a = 10}f(a);console.info(a)

解析: a指向的位置是栈 在栈中直接保存a=1  传入到函数内部 相当于有一个局部变量 var a=1 

a=10 在es6之前具有块级作用域的特点, 打印的结果是一个全局,所以打印出来的结果是1.

题5

var a = [1];function f(a){    a[1] = 10}f(a);console.info(a)

解析: 在函数进行传参的时候,函数内部的参数a 得到了全局a的值,这个赋值的过程,只复制了地址,因此指向同一个地址,在a中添加10,地址相同,添加的位置也就相同,所以打印出来的结果是,[1,10]

题6:

var a = [1];function f(a){    a[1] = 10    a = 3;}f(a);console.info(a)

解析:在栈中有a的地址,堆中有数值[1],将全局a的地址复制给局部的a,地址相同但是指向的堆的值是相同[1],在局部中添加10,全局的堆值也会发生改变,最有局部的堆地址被a=3 生成到栈中。

打印的是全局的所有打印出来的结果是[1,10]

四,深拷贝和浅拷贝的概念

一、如何区分深拷贝与浅拷贝

简单点来说,就是假设B复制了A;

当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝

如果B没变,那就是深拷贝

代码案例演示:

  var arr = [10, 20, 15, 453, 54, 20];

    var arr1 = arr;

    // 以为arr属于复杂的数据类型

    // arr1只是复制了arr的地址

    // 当改变arr1里面的数据是 arr也会跟着变化

    arr1[0] = 111;

    console.log(arr + '+' + arr1);

打印出来的结果

反之当arr1发生改变时,arr没有发生变化,则就是深拷贝。

五 . 如何实现浅拷贝和深拷贝

   1.利用递归

        

2.利用json的parse和stringify进行转化

个人以上自己的见解  


版权声明:本文为qq_59076775原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。