let 和 const
问什么要引入 let 和 const ?
解决 var 声明变量带来的问题。
在 ES6 之前,声明变量只能通过 var ,使用var声明变量存在以下问题:
允许重复的变量声明:导致数据被覆盖
变量提升:怪异的数据访问、闭包问题
全局变量挂载到全局对象:全局对象成员污染问题
// 变量提升:怪异的数据访问
if (Math.random() < 0.5) {
var a = "abc";
console.log(a);
}
else {
console.log(a);
}
console.log(a);//<0.5 abc >=0.5 undefined
// 变量提升:闭包问题
var div = document.getElementById("divButtons")
for (var i = 1; i <= 10; i++) {
var btn = document.createElement("button");
btn.innerHTML = "按钮" + i;
div.appendChild(btn);
btn.onclick = function () {
console.log(i); //输出11
}
}
// 全局变量挂载到全局对象:全局对象成员污染问题
var abc = "123";
console.log(window.abc);
为了解决上述问题,ES6 新增了 let 和 const
let 和 const 的特性 ?
块级作用域:代码执行时遇到花括号,会创建一个块级作用域,花括号结束,销毁块级作用域
变量赋值:在同一个作用域内,let 声明的变量能重新赋值,const 在声明变量的同时必须赋值 ,且值不可修改,在作用域外无法访问声明的变量
变量提升:let 和 const 均不会有变量提升,因此,不能在使用 let 和 const 声明变量之前使用它。底层实现上,let 声明的变量实际上也会有提升,但是,提升后会将其放入到“暂时性死区”,如果访问的变量位于暂时性死区,则会报错:“Cannot access 'a' before initialization”。当代码运行到该变量的声明语句时,会将其从暂时性死区中移除。
闭包问题处理:在循环中,用 let 声明的循环变量,会特殊处理,每次进入循环体,都会开启一个新的块级作用域,并且将循环变量绑定到该作用域(每次循环,使用的是一个全新的循环变量)。循环中使用let声明的循环变量,在循环结束后会销毁。
mdn文档链接:let const
解构赋值
什么是解构赋值,它能做什么
解构赋值是 ES6 提供的一种语法糖,通过解构赋值,可以将属性/值从对象/数组中取出,并赋值给其他变量。
// 取得对象的值
const obj = {a:1, b:2};
let a = obj.a;
let b = obj.b;
console.log(obj.a,obj.b);
//取得数组的值
const arr =[1,2];
let num1 = arr[0];
let num2 = arr[1];
以下的代码和上面的代码结果一致,区别是下面的用了解构赋值
// 取得对象的值
const {a,b}={a:1,b:2};
//取得数组的值
const [num1,num2]=[1,2];
解构赋值在对象和数组解构赋值的时候会有差别,对象是按照属性取值,数组是按照index的顺序取值
另外对于解构赋值还提供了默认参数和变量重命名的语法糖
//默认参数
let {a,b=5,c=1}={a:1,b:2};
let [num1,num2=10,num3=1]=[1,2];
//变量重名名
let {a:a1,b}={a:1,b:2};
console.log(a1)//1
console.log(a)//报错 Uncaught ReferenceError: a is not defined
通过解构赋值,快速实现两变量值交换
let a=11,b=22;
[b,a]=[a,b];
解构赋值的原理(实现方式)
其内在是针对可迭代对象的Iterator接口,通过遍历器(for of)按顺序获取对应的值进行赋值
mdn文档链接:解构赋值
展开运算符
怎么使用展开运算符偷懒
展开运算符可以在函数调用/数组构造时, 将数组表达式或者string在语法层面展开;还可以在构造字面量对象时, 将对象表达式按key-value的方式展开
//字符串展开
let str='bar';
const strArr = [...str]; // ["b", "a", "r"]
//数组展开
const arr1 = [1,2,3];
const arr2 = [...arr1,4]; // [1,2,3,4]
//对象展开
const obj1 = {a:1,b:2};
const obj2 = {...obj1,c:3}; // {a: 1, b: 2, c: 3}
偷懒操作:使用展开运算符,代替部分api功能,减少 api 的记忆
//替换arr.concat()
const arr3 = [...arr1,...arr2]; //等价 const arr3 = arr1.concat(arr2);
//替换arr.slice()
const arr3 = [1,2,3,4].slice(2) //等价 [1,2,arr3]= [1,2,3,4]
const arr3 = [1,2,3,4].slice(1,3) //等价 [1,arr3,4]= [1,2,3,4]
//替换arr.push()
const arr3 = [1,2,3,4].push(arr)//等价 arr3 = [1,2,3,4,arr]
//替换 Object.assign() 相同
const obj3 = {...obj1,...obj2} //等价 const obj3 = Object.assign({},obj1,obj2)
展开运算符除了能对字符串,数组,对象展开外,还能将剩余参数重新收集为数组和对象
//函数调用时使用(剩余参数)
let a1=1,a2=2,a3=3;
function sum(a1,...arr){
console.log(arr)// [2,3]
return a1*2 + arr.reduce((a,b)=>a+b)
}
sum(a1,a2,a3) // 7
// 数组收集
[1, ...arr] = [1, 2, 3, 4] // arr=[2,3,4]
//对象收集
{ a : 1 , ...obj } = {a:1, b:2} //obj={b:2}
mdn 文档:展开运算符 剩余参数
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!