一.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] = 10a = 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进行转化

个人以上自己的见解