1. ES6 简介
1.1: 什么是 ES6 ?
ES 的全称是 ECMAScript , 它是由 ECMA 国际标准化组织,制定的一项脚本语言的标准化规范。
年份 | 版本 |
---|---|
2015年6月 | ES2015 |
2016年6月 | ES2016 |
2017年6月 | ES2017 |
2018年6月 | ES2018 |
1.2:为什么使用 ES6 ?
每一次标准的诞生都意味着语言的完善,功能的加强。JavaScript语言本身也有一些令人不满意的地方。
- 变量提升特性增加了程序运行时的不可预测性
- 语法过于松散,实现相同的功能,不同的人可能会写出不同的代码
2.1:let关键字
let关键字用来声明变量,使用let声明的变量有几个特点:
- 1)不允许重复声明
- 2)块儿级作用域
- 3)不存在变量提升
- 4)不影响作用域链
应用场景:以后声明变量使用let 就对了
1-let关键字声明的变量只在所处的块级作用域有效。
(var关键字不具备这个特点)
块级作用域是由{}产生的 if{} for{},只能在{}的内部使用,外部是访问不到的
2.使用let关键字声明的变量具有块级作用域
// var和let在此处的区别:var声明的name是一个全局变量,故在{}外面是可以访问的,而stuName具有块级作用域,它访问权限只在{}内,故在外面访问不到
{
var name = "艾斯"
let stuName = "路飞"
}
console.log(name)
console.log(stuName)
2-let关键字声明的变量不存在变量提升
(使用let声明变量只能先声明在使用)
console.log(sex)
let sex = "男"
console.log(sex)
3.不影响作用域链
function test() {
let a = 10
function test2() {
console.log(a)
}
test2()
}
test()
4-let关键字声明的变量具有暂时性死区特性
var num = 10;
if (true) {
console.log(num);
let num = 20;
}
2.2:const关键字
const关键字用来声明常量,const声明有以下特点:
- 1)声明必须赋初始值
- 2)标识符一般为大写
- 3)不允许重复声明
- 4)值不允许修改
- 5)块儿级作用域
注意:对象属性修改和数组元素变化不会出发const 错误应用场景:声明对象类型使用const,非对象类型声明选择let
1-const关键字声明的常量具有块级作用域
if (true) {
const a = 10;
}
console.log(a); //a is not defined
2-const关键字声明常量时必须赋值
const b;
console.log(b); //missing initializer in const declaration
3-const关键字声明常量并赋值后常量的值不能修改
1>对于基本的数据类型(数值型、字符串型)一旦赋值,是不能修改的
const PI = 3.14;
PI = 10;
console.log(PI);
2>对于复杂的数据类型(数组,对象),虽然不能重新赋值,但是可以更改内部的值
const arr = [100, 200];
arr[0] = 'a';
arr[1] = 'b';
console.log(arr);
arr = [1, 2]; //Assignment to constant variable 无法对常量进行赋值
2.3:let、const、var关键字之间的区别
1.使用var声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象(var:函数级作用域、变量提升、值可更改)
2.使用let声明的变量,其作用域为该语句所在的代码块内,不存在变量提升。(let:块级作用域、不存在变量提升、值可更改)
3.使用const声明的是常量,在后面出现的代码中不能再修改该常量的值(const:块级作用域、不存在变量提升、值不可更改)
setTimeout()只是将时间插入了“任务队列”,必须等到当前代码(执行栈)执行完,主线程才会去执行它指定的回调函数
3.1:数组的解构赋值
解析表示对数据结构进行分解, 赋值值变量的赋值。
在ES6中, 允许按照一一对应的方式, 从数组或对象中提取值, 然后将提取出来的值赋值给变量。
1.数组的解构赋值,就是将数组中的值提取出来,然后赋值给另外的变量。
let [a, b, c] = [1, 2, 3];
console.log(a);
console.log(b);
console.log(c);
console.log(d); //undefined
2.对象解构允许使用变量的名字匹配对象属性, 如果匹配成功就将对象中属性的值赋值给变量。
var obj = {
name: "张三",
age: 10
}
console.log(obj.name); //获取,输出“张三”
let obj = {
name: "李四",
age: 20
}
>1变量———具体被解构的对象
//let{name,age}=obj;
let {
name,
age
} = obj;
console.log(name);
console.log(age);
>2属性名:变量名————具体被解构的对象
// let {name: myName,age: myAge} = obj;
let {
name: myName,
age: myAge
} = obj;
console.log(myName);
console.log(myAge);
4.1:箭头函数的语法
箭头函数基本语法
()=>{}
箭头函数以小括号开头,在小括号中可以放置参数,小括号的后面要跟着箭头(=>),
箭头后面要写一个大括号来表示函数体,这是箭头函数的“固定用法”。
//箭头函数调用//:因为箭头函数没有名字,我们通常的做法是把箭头函数赋值给一个变量,
变量名就是函数名,然后通过变量名去调用函数即可。
4.2:箭头函数的特点
特点1:省略大括号
在箭头函数中,如果函数体中只有一句代码,且代码的执行结果就是和拿书的返回值,此时
可以省略函数体大括号。
特点2:省略参数外部的小括号
在箭头函数中,如果形参只有一个,可以省略参数外部的小括号
// 箭头函数
// 1.穿件一个无参的箭头函数
let fun_1 = () => {
console.log("我是一个无参箭头函数")
}
fun_1()
// 2.有参的箭头函数
let fun_2 = (a, b) => {
console.log(a, b)
}
fun_2(1, 2)
// 3.如果参数只有一个,可以简写(将()省略)
let fun_3 = a => {
console.log(a)
}
fun_3(100)
// 4.如果函数体中只有一个语句,则{}也可以省略
let fun_4 = a => 10
fun_4(200)
// 5.this指向
var obj_1 = {
name: "king",
fun() {
setTimeout(() => {
console.log(this)
}, 1000)
},
fuc: function() {
setTimeout(function() {
console.log(this)
}, 1000)
}
}
obj_1.fun()
obj_1.fuc()
4.3:箭头函数中的this关键字
ES6中,“箭头函数”不绑定“this关键字”,它没有自己的“this关键字”,如果在“箭头函数”中使用“this关键字”
那么“this关键字”只想的是“箭头函数”定义位置的上下文“this”。也就是说,“箭头函数”被定义在哪,“箭头函数”中的“this”就指向谁。
5:变量的解构赋值
5.1基本用法
ES6允许按照一定模式从数组和对象中提取数据,对变量进行赋值,这被称为解构,只要等号两边的模式相同,左边的变量就会被赋予对应的值。本质上,这种写法属于模式匹配
let [a,b,c] = [1,2,3]
//等同于
let a=1
let b=2
let c=3
let [foo,[[bar],baz]] = [1,[[2],3]
//foo 1
//bar 2
//baz 3
如果解构不成功,变量的值就等于undefined
let [foo] =[/解构不成功undefined
let [bar,foo] =[1]1/解构不成功undefined
5.2默认值
解构赋值允许指定默认值
let [foo = true] = [
console.log(foo)l/true
ES6内部使用严格模式相等运算符(m"=),判断一个位置是否有值,当一个数组成员严格等于undefined,默认值才会生效
let [x=1] = [undefined]
console.log(x) //1
let [x=1] = [null]
console.log(x) //null
如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候才会求值
function fn(){
return 2
}
let [x = fn()] =[1]
console.log(x)
默认只可以引用解构赋值的其它变量,但该变量必须已经声明
let [x = 1,y =x] = [] //x=1,y=1
let [x = 1,y = ×] =[2] //x=2,y=2
let [x = 1,y = x] = [1,2] //x=1,y=2
let [x = y,y = 1]= [] //报错,因为在给x赋值为y时,y还没有声明
5.2:对象解构
数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值
一、对象解构赋值的原理
1、模式(结构)匹配
{}={}
2、属性名相同的完成赋值
const { age, username } = { username: 'Alex', age: 18 };
//18 "Alex"
//完整形式为:
const { age: age, username: username } = { username: 'Alex', age: 18 };
// 18 "Alex"
console.log(age, username);
//取别名
const { age: age, username: uname } = { username: 'Alex', age: 18 };
console.log(age, uname);
二、对象解构赋值的注意事项
1、默认值的生效条件: 对象的属性值严格等于 undefined 时,对应的默认值才会生效
const { username = 'ZhangSan', age = 0 } = { username: 'alex' };
console.log(username, age); //默认值 用 = 。非 :
2、默认值表达式:如果默认值是表达式,默认值表达式是惰性求值的
3、将一个已经声明的变量用于解构赋值:如果将一个已经声明的变量用于对象的解构赋值,整个赋值需在圆括号中进行
let { x } = { x: 1 };
console.log(x); //报错。重复声明
let x = 2;
({ x } = { x: 1 });
console.log(x); //1
三、对象解构赋值的应用
函数参数的解构赋值
//不使用解构赋值的时候:
const logPersonInfo = user => console.log(user.username, user.age);
logPersonInfo({ username: 'alex', age: 18 });
// alex 18
//使用解构赋值的时候:
const logPersonInfo = ({ age = 0, username = 'ZhangSan' }) => //形参
console.log(username, age);
logPersonInfo({ username: 'alex', age: 18 });
// alex 18
///相当于{ age:age, username:username }={ username: 'alex', age: 18 }