const特点
(1)编码规范:命令为大写
(2)必须付初值,否则会报错,程序停止
(3)常量的值不能修改
(4)块级作用域
解构赋值 -- 按照数组或者对象的结构对变量赋值
数组的结构赋值
const F4 = ['小沈阳', '刘能', '赵四', '宋小宝']
let [FN1, FN2, FN3, FN4] = F4;
console.log(FN1)
console.log(FN2)
console.log(FN3)
console.log(FN4)
FN1 = '张飞'
FN2 = '关羽'
FN3 = '赵云'
FN4 = '刘备'
console.log(FN1)
console.log(FN2)
console.log(FN3)
console.log(FN4)
console.log(F4)
输出结果如下:
可以看到,修改变量后的值,不影响之前的F4的值
典型案例
(1)变量交换
如下,不需要第三个临时变量,可以直接实现两个变量的交换
let a = "学校";
let b = "医院";
[a, b] = [b, a];
console.log(a)
console.log(b)
对象的解构赋值
const ZHAOBENSHAN = {
name: '赵本山',
age: 18,
xiaopin: function () {
console.log('我会演小品')
}
}
let {xiaopin} = ZHAOBENSHAN;
xiaopin(); // 我会演小品
Js的内存结构
原始类型与引用类型
栈区
由编译器自动分配释放 ,存放函数的参数值,局部变量的值等,内存的分配是连续的,那么浏览器执行JS的时候栈区是多少呢,如何查看呢?没有找到对应的值,只在网上找到了一个测试的方法Brower Javascript Stack size limit,里面给出了测试的结果,那么栈到底是用来做什么的呢?栈由一个一个的栈帧组成,一个栈帧中包含了一个方法调用所需用到的所有数据:包括参数,返回地址,本地变量
等等。在栈区分配的对象是本地变量的一部分。
栈帧只存在于方法调用过程中,这样做的好处是不需要担心栈分配的对象会造成内存溢出,但相对的一旦方法调用结束了我们就再也没法访问这个对象了。
只有在编译时就知道大小的对象才能在栈中分配内存。我们都知道栈帧的大小在编译时期就已经确定了,也正是因为这样才可以通过相对栈顶指针固定的偏移量来访问栈中的对象
堆区
堆区是一般由程序员分配释放, 若程序员不释放,程序结束时可能由操作系统回收.类似于链表,在内存中的分布不是连续的,它们是不同区域的内存块通过指针链接起来的,从F12就可以看到堆区大小,一般内存溢出也就是这里了
JavaScript的堆与栈
JavaScript的原始类型保存在栈区,对象保存在堆区,具体如下:
原始类型:数值、字符串、布尔、null、undefined
引用类型:对象
深拷贝与浅拷贝
深拷贝:修改新变量的值不会影响原有变量的值。默认情况下基本数据类型都是深拷贝,简单点说就是都是新的存储空间
浅拷贝:修改新变量的值会影响原有的变量的值。默认情况下引用类型都是浅拷贝,存储空间没有变化
典型案例如下:
let temp1 = 10;
let temp2 = temp1;
temp1 = 30;
console.log(temp1) // 30
console.log(temp2) // 10
let xiaohong = {
name:'小红',
age:18
}
let xiaoming = xiaohong;
xiaoming.name = '小明'
console.log(xiaohong) //{name: '小明', age: 18}
典型案例2 解构赋值与对象结构是深拷贝还是浅拷贝?
首先,非引用类型都是深拷贝,一维数组或者对象的值直接赋值给变量,肯定是深拷贝。
const F4 = ['小沈阳', '刘能', '赵四', '宋小宝']
let [FN1, FN2, FN3, FN4] = F4;
console.log(FN1) // 小沈阳
console.log(FN2) // 刘能
console.log(FN3) // 赵四
console.log(FN4) // 宋小宝
FN1 = '张飞'
FN2 = '关羽'
FN3 = '赵云'
FN4 = '刘备'
console.log(FN1) // 张飞
console.log(FN2) //关羽
console.log(FN3) // 赵云
console.log(FN4) // 刘备
console.log(F4) // ['小沈阳', '刘能', '赵四', '宋小宝']
那么,如果对象中的引用直接赋值给变量呢?
let obj = {
name: '赵本山',
age: 30,
xiaopinObj: ['卖拐', '小崔说事', '卖车']
}
let {name, age, xiaopinObj} = obj;
xiaopinObj[0] = '就差钱';
console.log(obj)
回显如下,也很明显了,xiaopinObj改变的是变量,但是变量里面保存的引用地址没有变,两个还是同一个数组。
结论:
解构赋值,如果所解构的原对象是一维数组或对象,其本质就是对基本数据类型进行等号赋值,那它就是深拷贝;
如果是多维数组或对象,其本质就是对引用类型数据进项等号赋值,那它就是浅拷贝;
最终的结论就是:解构赋值是浅拷贝(因为它确实不能对多维数组或对象达到深拷贝的作用);