这是一道几乎所有面试都会面试的问题,为什么会有这个问题的因为这个问题涉及js基础知识比较多,所以经常拿来问,我们看下会涉及哪些知识:
一 js基本类型的分类以及包含哪些?
基础类型:undefined 、 null、number、string、boolean、symbol
引用类型:object对象类型(Object 、Array 、Function 、Data)
对于这两种类型有几个关键知识点:
1 基础类型是按照值进行访问的,可以操作保存在变量中的实际的值。对于引用类型,javascript是不允许直接访问值的,不能直接操作对象的内存空间,在操作对象时候,实际操作是引用,而不是实际的引用。
2 基础类型存在于栈中,
引用类型的值是同时保存在栈内存和堆内存中的对象。
二:js的变量的存储方式 栈(stack) 和 堆(heap)
关于栈和堆有几个关键点需要了解
1 栈(stack)是后进先出,堆(heap)是先进先出。
2 栈(stack)内存是我们手动分配, 堆(heap)内存是自动分配。
接下来我们要介绍js的浅拷贝和深拷贝
首先我们要把对象和数组的赋值操作划分为深浅拷贝之外,他们不属于这之中,至少在我这边,相信这样大家会更容易理解深浅拷贝。
如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。
1对象和数组的赋值操作
对象:
对于这种对象赋值,两个对象指向的事同一块内存地址,当对象获取key值然后重新赋值,是可以改变值的,这样可以寻找到对象的指针。如果直接改变值,这样是不可以改变的。因为寻不到地址。
数组:
2 浅拷贝
浅拷贝在我看来就是对一 "层" 简单类型的拷贝,对于在a对象里面的包含b对象的浅拷贝,拷贝为c对象后 ,c对象中b'对象和a对象中的b对象指向的事同一块内存地址,对于a对象以及c对象的'一层',基本类型的拷贝,实际上指向的是不同的内存地址。我们举个例子:
第二层逻辑改变是相互不影响,三层逻辑是相互影响的,二层实际上拷贝的基本类型,所以指向不同内存地址,三层逻辑是引用类型,实际浅拷贝并没有进行拷贝,二者指向的还是同样内存地址。对于数组也相当于引用类型,四层逻辑二者指向同样的内存地址。
也就是记住浅拷贝只对一层有效,是指向不同内存地址:我们再看下一个例子:
3 实现浅拷贝的方法
object.assign()自己实现
// 只复制第一层的浅拷贝function simpleCopy(obj1) {var obj2 = Array.isArray(obj1) ? [] : {};for (let i in obj1) {obj2[i] = obj1[i];}return obj2;}var obj1 = {a: 1,b: 2,c: {d: 3}}var obj2 = simpleCopy(obj1);obj2.a = 3;obj2.c.d = 4;alert(obj1.a); // 1alert(obj2.a); // 3alert(obj1.c.d); // 4alert(obj2.c.d); // 4
4 实现深拷贝方法
JSON.stringify与JSON.parseArray的slice和concat方法 返回新数组自己实现深拷贝以及有哪些缺点
function deepCopy(obj1) {var obj2 = Array.isArray(obj1) ? [] : {};if (obj1 && typeof obj1 === "object") {for (var i in obj1) {var prop = obj1[i]; // 避免相互引用造成死循环,如obj1.a=objif (prop == obj1) {continue;}if (obj1.hasOwnProperty(i)) {// 如果子属性为引用数据类型,递归复制if (prop && typeof prop === "object") {obj2[i] = (prop.constructor === Array) ? [] : {};arguments.callee(prop, obj2[i]); // 递归调用} else {// 如果是基本数据类型,只是简单的复制obj2[i] = prop;}}}}return obj2;}var obj1 = {a: 1,b: 2,c: {d: 3}}var obj2 = deepCopy(obj1);obj2.a = 3;obj2.c.d = 4;alert(obj1.a); // 1alert(obj2.a); // 3alert(obj1.c.d); // 3alert(obj2.c.d); // 4
计算机中的堆和和栈(物理内存上的解释) - bai___DDD的博客 - CSDN博客【JS】深拷贝与浅拷贝的区别,实现深拷贝的几种方法 - 听风是风 - 博客园堆、栈在内存中的存储位置----详解 - 烽火前秦路 - CSDN博客