前端学习笔记三——堆栈、闭包、深浅克隆

7 篇文章 0 订阅

堆栈

一、先来看一道简单的题目

let a={},b='0',c=0;
    a[b]="第一";
    a[c]="第二";
    console.log(a[b]);

输出:“第二”
先理解一下堆和栈的概念:
栈:存放基本数据类型的内存空间
堆:存放引用数据类型的内存空间
在定义a={}时会将a这个引用数据类型存到一个堆中,而a指向的则是这个堆的一个16进制内存地址,而b和c都存在栈中,在进行a[b]="第一"这个操作时相当于给堆空间添加了一个属性名为‘0’的属性,但是由于对象的属性名不能重复,所以a[0]和a[‘0’]指向同一属性,所以会修改了同一个属性
在这里插入图片描述
思考一下下面的代码输出什么:

let a={},b={m:2},c={n:12};
    a[b]="第一";
    a[c]="第二";
    console.log(a[b]);

还是"第二",这是因为a[b]和a[c]都等价于a[object:Object];在存储对象到堆中会自动转换为字符串存储

闭包

什么是闭包?简单的来说就是函数里面嵌套一个函数
定义:闭包是指有权访问另一个函数作用域的函数
那么作用就很明显了:
1、可以在函数外部访问到函数内部的变量
2、可以将变量保存在内存中不随函数的销毁而销毁
来看一道简单的小题目:

var test=(function(i){
   return function(){
   alert(i*=2);
   }
   })(2);
   test(5);

答案是弹出了字符串’4’
在这里插入图片描述

这里的函数是一个立即执行函数,在执行test(5)需要先找到上级作用域是否有i变量,而上级作用域就是创建函数的上级作用域也就是在栈中,有i=2,所以在test(5)的空间里的i=2。
不清楚再来看一个题:

  var a=0,b=0;
    function A(a){
        A=function(b){
            alert(a+b++);
        }
        alert(a++);
    }
    A(1);
    A(2);

答案是弹出‘1’和’4’
在这里插入图片描述
根据图来看,在执行到function A时会创建一个堆来存储A,再到A(1)会分配一个执行栈来执行这个语句,在ECStack1中,也就是执行函数A里的内容, A=function(b){ alert(a+b++); }相当于重写了函数A的指向地址,重新分配了一个堆地址,但在ECStack1已经完成了a=1和alert(a++)的操作,所以a已经变成了2;再到执行A(2)的时候则执行alert(a+b++),此时a=2,b=传进来的2,所以弹出’4’

深克隆和浅克隆

浅克隆:直接将存储在栈中的值赋值给对应变量,如果是基本数据类型,则直接赋值对应的值,如果是引用类型,则赋值的是地址
深克隆:就是把数据赋值给对应的变量,是拷贝对象各个层级的属性,在内存中开辟一块新内存,将原对象中的所有值全部复制过去,与原对象完全脱离,修改新对象中的属性值不会影响原对象

let obj={
         a:100,
         b:[10,20,30],
         c:{
             x:10
         },
         d:/^\d+$/
        };

想一想怎么把obj进行一个浅克隆或者深克隆?
浅克隆:
1.ES6新增的拓展运算符

let obj2={...obj};

2.for循环

 let obj2={};
        for(let key in obj){
            if(!obj.hasOwnProperty(key)) break;
                obj2[key]=obj[key];
            
        }

在这里插入图片描述
深克隆:
1.JSON.parse(JSON.stringify())

let obj2 = JSON.parse(JSON.stringify(obj))

但是要注意:
1.对象中的方法不能进行copy,会自动忽略
2.对象中的Date时间不能进行copy, JSON.stringify方法会将日期自动转换为常规日期格式
3.正则表达式不能copy , JSON.stringify方法会将正则变为空对象
所以我们需要用递归来解决这些问题

function clone(obj ){
	// 过滤特俗情况
	if(obj===null) return obj
	if(typeof obj !=='object') return obj
	if(obj instanceof RegExp){
		return new RegExp(obj)
	}
	if(obj instanceof Date){
		return new Date(obj)
	}
	let newObj = new obj.constructor
	for(let key in obj){
		if (obj.hasOwnProperty(key)) {
			newObj[key] = clone(obj[key] )
		}
	}
	return newObj 
}
let obj2 = clone(obj)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值