ES6
1、let的使用
1.声明变量的方法(let和const)
let 和 const 命令是es6新增的语法
作用:是用来声明变量 和var的作用一样,但是所声明的变量,只在let命令所在的代码块内有效
区别:
1.let在同意作用域内 可以重新赋值但是不能重复声明
2.const声明的是常量 声明过后 就不能在重新声明 或重新赋值。
【注】
1.存在块级作用域{}
2.不存在声明提升
3.不允许重复声明(包括普通变量和函数参数)
变量绑定
//1.let声明的变量 只在let所在的作用域内起作用(变量绑定)
var a = 123;
if(true){
a = 456;
console.log(a);
在下面进行let声明
let a;
}
局部作用域(function关键字)
//通常情况下 如果我们需要一个变量在规定的作用域内起作用 那么我们就需要使用function关键字来搭建一个局部作用域
(function(){
var a = 1;
}())
console.log(a);
块级作用域
//但是在ES6 的情况下 引入了let 只要存在{}就可以形成一个块级作用域 不管是if结构 还是for循环结构 只要有{}存在
//即形成了块级作用域
{
let s = 8;
}
console.log(s);
var 声明变量 变量提升的问题
//需求:在函数调用时 实时的打印出当前的时间
//在if结构里面使用var声明 {}没办法形成块级作用域 那么if结构里面的变量声明就会覆盖掉全局的变量声明
//所以打印出来的undefined
//解决办法:在if结构里面使用let声明变量 使其在if结构里面形成一个块级作用域
var time = new Date();
function fn(){
console.log(time);
if (false) {
//var time = "明天是端午节";
let time = "明天是端午节";
}
}
/*function fn(){
var time;
console.log(time);
if (false) {
time = "明天是端午节";
}
}*/
fn();
//(3) for循环中 循环变量泄露为全局变量的问题
for(var i = 0;i<5;i++){
setTimeout(function(){
console.log(i);
},1000)
console.log(111);
}
console.log(123);
js语言的一大特性:
单线程 同一时间内只做一件事
任务队列:
所有的任务都需要排队 前面的一个执行完 才会执行后面的任务
事件循环:
主线程会不断循环的取任务队列里面去读取任务(Event Loop)当遇到异步任务完成 或者某个事件被触发
那么相应的回调函数 或者 函数体就会被拉到主线程里面去执行
2、解构赋值
什么叫解构?
我们通俗的归纳为:按照一定模式,从数组和对象中提取值,对变量进行赋值。
再者,其本质上讲,解构赋值就是模式匹配。
下面我们来举个例子:
//基础赋值方式:
var a = 1,b = 2, c = 3 ;
var a = 1 ;
var b = 2 ;
var c = 3 ;
//解构赋值
var [a,b,c] = [1,2,3];
console.log(a,b,c);//123
那么也就是说,如果想要解构赋值成功 那么就必须保证两边的模式完全一样。
好了,问题来了,假如解构不成功呢??
let [r] = [];
console.log(r);//undefined 这个就想var 声明了变量之后 不进行赋值
var a;
好了 我们总结就是:如果解构不成功 那么变量的值就等于undefined
说到这里,我们就还需要了解一下什么叫__不完全解构__?
不完全解构:指的是等号左右两边模式一样 但是只匹配到右边的一部分数据
例如下面:
let [x,y] = [1,2,3];
console.log(x,y);
因此我们就会发现:不完全解构的情况下 也可以进行解构赋值 只是后面放数值的数组都有多的数字
另外我们还需要注意如果等号右边不是数组,那么就会报错 因为模式不一样
// let [m] = 1;
// let [m] = false;
// let [m] = null;
// let [m] = {};
// console.log(m);//{} is not iterable 因为{}不可使用下标进行迭代
补充一点对象的解构赋值是怎么样的呢?
let {a,b} = {a:" aaa" ,b:" bbb" };//a=aaa ,b=bbb
let {a:b} = {a:" aaa" };//a=aaa
let{a,b= 5}= {a: 1};//a=1,b=5
【注意点总结】:
1.解构赋值是允许设置默认值的 但是如果要启用默认值 那么 这个变量的值就必须严格等于undefined
2.如果设置的默认是一个表达式 那么这个表达式只是在需要启用默认值的时候才会运算
3.默认值可以使用其他变量 但是前提是赋值的这个变量必须是提前声明过的
3、模版字符串
var stu = {
name : "lisa",
age : 12,
place : "湖北武汉",
grade : 6
}
document.querySelector("p").innerHTML = "我叫" +stu.name+",我今年"+stu.age+"岁了,我住在"+stu.place+",今年上"+stu.grade+"年级";
document.querySelector("p").innerHTML = "我叫" +stu.name+",我今年"+stu.age+"岁,我住在"+stu.place+",今年上"+stu.grade+"年级";
拼接字符串的弊端:
1.拼接太麻烦 需要多次分割 不便于维护
2.所有拼接的字符串只能一行 显示 太长
所以ES6我们用模板字符串了。
那么,模板字符串怎么用呢?
1.将变量或表达式直接嵌入字符串
2.使用反引号(``) 拼接多行字符串
嵌入变量
let obj = {"name" :"john",”age":20};
let{name,age} . obj;
console . log( `${name }的年龄是${age}` );
嵌入表达式(使用上上个案例)
//在${}可以放入任意的js表达式 可以进行运算
function age (num){
return num -1;
}
document.querySelector("p").innerHTML = `我叫${stu.name},我今年${stu.age}岁了,我上${stu.grade -1},我住在${stu.place}`;
4、箭头函数( Arrow Function )
【注意】
1.只含有1个表达式
2.含有多条语句
3.this的指向问题
ES5
/*var foo = function(){
return 1 ;
}
console. log(foo());*/
ES6
let foo=()=>1;
let foo = (a)=>{
let b=10;
return a+b;
}
console . log(foo(10));//20
5、set结构和map结构
set结构
let set = new Set([1,2,3,4,4]);
构造函数,值不重复
元素 | 含义 |
---|---|
[…set] | …扩展运算符,将类数组对象转换以逗号分割的序列 |
for of | 遍历 |
set.size | 长度 |
set.add(0) | 新增加一个元素 |
set.delete(0) | 删除一个元素 |
set.has(0) | 表示当前元素中是否含有某一个元素 |
set.clear() | 清空结构 |
keys() :返回键名的遍历器
for (let item of set.keys()) {
console.log(item);
}
values() :返回键值的遍历器
entries() :返回键值对的遍历器
forEach() :使用回调函数遍历每个成员
set.forEach((value, key) => console.log(value * 2));
map结构
let map = new Map([["name","john"],["age",30]]);
map.set(1,1);
map.size //长度
map.set(key,value);
map.get(key);
map.delete(key);
map.has(key);
map.clear();
keys() :返回键名的遍历器
values() :返回键值的遍历器
entries() :返回键值对的遍历器
for (let [key, value] of map.entries() ){ console.log(key, value); }
forEach() :使用回调函数遍历每个成员
map.forEach((value, key) => console.log(value*.2))