一,let
let 和 var 区别
1. let关键字声明的变量不可以重复声明,会报错
// var关键字定义的变量会有变量提升的问题
console.log(a); // undefined
var a = 10;
console.log(a); // 10
var a = 20;
console.log(a); // 不会报错 20
let b = 10;
console.log(b); // 10
let b = 30;
console.log(b); // 报错 不可以重复声明
2. let关键字声明的变量不存在变量提升的问题,会报错
console.log(c); // 报错 不存在变量提升
let c = 'aaa';
3. 在块级作用域内通过let关键字声明的变量,在定义的作用域外部获取不到对应的变量
作用域:
全局作用域
局部作用域(函数作用域)
块级作用域
// es6中新增加了一个块级作用域 通过let声明的变量 在{}内部属于块级作用域
if(true) {
let e = 12;
}
// console.log(e); // 报错 e is not defined
// var 定义的变量不存在块级作用域(全局 函数)
for(var i=0; i<aLi.length; i++) {
console.log(aLi[i]);
}
console.log(i) // 3
for(let j=0; j<aLi.length; j++) {
console.log(j)
}
// console.log(j) //报错 j is not defined
4. 暂时性死区(当前作用域内不允许同名的变量进来),在块级作用域内let声明的变量会形成一个封闭性的死区,只能在声明之后调用,否则会报错
let y = 9;
function fun1() {
// console.log(y); // 报错
let y = 888;
console.log(y)
}
fun1();
二,const
1. const关键字声明的变量不可以重复声明,会报错
const定义基本数据类型 基本数据类型存的就是值,值不能改变
const定义引用数据类型 引用数据类型存的是地址,地址不能修改,内容可以修改
const num = 10;
console.log(num); // 10
const num = 20;
console.log(num); // 报错
const 关键字定义的是一个常量,并且是只读 const定义的变量在声明的时候就必须赋值
赋值之后不允许修改
const str;
console.log(str); //报错
const arr = [1,2,3];
const arr1 = arr; // [1,2,3] 赋值的是地址(指针)
console.log(arr1)
arr1[1] = 888; // 引用数据类型内容修改无影响 因为地址没变
console.log(arr) // [1,888,3]
console.log(arr1) // [1,888,3]
// arr1 = [9,8,9]; // 开辟了一个新的地址,const arr1(arr1存的地址变了就报错了)
// console.log(arr1);
const obj1 = {
name: 'zs',
age: 18
}
const obj2 = obj1; //赋值的是地址
console.log(obj2.age) // 18
// 冻结 冻结了之后 内容修改就不生效了,修改不会报错
Object.freeze(obj2)
obj2.age = 28; // 因为obj2被冻结了,所以修改不生效,但不会报错
2. const关键字声明的变量不存在变量提升的问题,会报错
3. 在块级作用域内通过const关键字声明的变量,在定义的作用域外部获取不到对应的变量
4. 暂时性死区(当前作用域内不允许同名的变量进来) 在块级作用域内const声明的变量会形成一个封闭性的死区,只能在声明之后调用,否则会报错
三.解构赋值
1.从数组和对象中提取值,对变量进行赋值,这被称为解构
let a1 = [1,2,3];
let a = a1[0];
let b = a1[1];
let c = a1[2];
2. 数组的解构赋值 从左向右依次赋值
let [a,b,c,d] = [1,2,3];
console.log(a,b,c,d); // 1 2 3 undefined
let [,b,,d] = [1,2,3,4]
console.log(b,d) // 2, 4
3 对象的解构 按照对象里的key(属性名解构)
let obj1 = {
// key: value
name: 'zs',
age: 18,
}
let {name:aaa} = obj1; //给name取别名
console.log("name:",name,'aaa:', aaa) //name: aaa: zs
let {age,name} = obj1
console.log(age, name) //18 zs
4. 字符串解构
let str = 'hello';
let [e,f,g,h,i,j,k] = str;
console.log(e,f,g,h,i,j,k) // h e l l o undefined
解构应用 :交换x,y的值
let x=4;
let y=3;
[y,x]=[x,y]
function fun([x,y = 99,z = 100]) {//y=99,z=100是设置默认值
console.log(x, y, z)
}
fun([1,2, null]) //1,2,null
// 没有形参的情况下 可以通过arguments来获取参数
function fn1() {
// arguments 可以获取调用方法时传递进来的实参
console.log(arguments)
}
四.扩展运算符
1.数组的复制(数组的深拷贝)/ 对象的复制(对象的深拷贝)
扩展运算符 ...
let a1 = [1,2,3];
let a2 = [...a1]; //数组的深拷贝
console.log(a2); // [1,2,3]
a2[1] = 4;
console.log(a1); // [1,2,3]
console.log(a2); // [1,4,3]
let obj1 = {
age: 18,
name: 'zs'
}
let obj2 = {...obj1};
console.log(obj2.age, obj2.name) //18 zs
obj2.age = 28;
console.log(obj1.age) // 18
2.数组中的一部分/ 对象的一部分
3.数组的合并/ 对象的合并(相同属性 后面会覆盖前面)
let obj1 = {
age: 18,
name: 'zs'
}
let obj3 = {
// key 是唯一的
height: '170cm',
weight: '123kg',
age: 28
}
let obj6 = {...obj3,...obj1};
console.log(obj6); //{height: "170cm", weight: "123kg", age: 18, name: "zs"}
console.log(obj6.age); // 18
4.可以将类数组转换成数组
// 类数组 只有长度
let aLi = document.getElementsByTagName('li');
aLi.push('<li>4</li>');
console.log(aLi); //类数组 无法使用 push方法
// 类数组转换成数组
let a1 = [...aLi]
console.log(a1) //是一个真正的数组