一、ES6简介
ECMAScript6.0的简称,被认为是下一代JavaScript的代称。ES6的目标使JS这门语言可以编写复杂的大型的企业级应用。
1998年2月 ECMAscript2.0(第一版)
1999年12月 ECMAscript3.0
2009年 ECMAscript5.0
2015年6月 ECMAscript6.0
2016年 ES7
。。。。
2020 ES2020
二、ES6相比ES5的变换
更安全、更合理、更严谨
2.1 新增项
let 与 const
解构赋值
字符串、数字、布尔、object 都相应的扩展
iterator 和 generator (早期异步编程)
promise和 async…await( 流行异步编程 )
模块化…
2.2 语法糖
ES6的功能使用ES5也能实现,但过于繁琐,使用上做了一个封装,使用起来更方便。
面向对象:
构造函数
原型对象
继承,原型链继承
经典继承、组合继承…
ES6面向对象:
class关键词
继承:extends 关键词
vscode插件:
jquery code snippets
live server
node-snippets
open in brower
三、let与const
3.1 let 作用
作用:声明变量
3.2 let 与 var 的区别
a) let是块作用域,var是函数作用域
let 和 var 的使用方法一样
let 在 if、for循环语句等声明的变量是局部变量
let相比var有什么好处?
let声明的变量防止 全局污染。
b) let不存在变量提升,var可以的
leta声明的变量必须先声明再使用(暂时性死区,TDZ)
好处?对于开发者来说,代码更严谨,保存信息一目了然。
c) let在同一作用域中不允许重复声明,var可以的
注意,函数的形参也不能重复声明。
好处: 在复杂的项目开发中,变量的重复声明在所难免,var的情况不易察觉,容易引起bug,而let直接报错比较直观,容易排除。
总结: 学会了let,可以抛弃var
3.3 案例: let变量在for循环中的应用
总结:let变量特别适合在for循环中使用, let变量在for循环中,有父级、子级作用域的概念。for循环圆括号内的let变量属于父级作用域, for循环的大括号内的let变量属于子级作用域。
3.4 const常量
const作用:用来保存项目中不经常改变的内容。像公司地址,数据库的名称,账号、密码、圆周率等等
特征:
1) 声明和赋值必须同时进行
2) 一旦被赋值后不可被改变
- 其他和let一样
const ADDRESS = “西安市凤城四路128号鼎和国际大厦”;
const PI = 3.14159;
// ADDRESS = “凤城五路129号” ;//error: Assignment to constant variable.
注意:const常量中如果存储是数组、对象(引用类型)的话,const只能保证地址不能更改,至于地址指向的内容是可以修改的。
3.5 与顶级对象的解绑
// ES6之前,声明的全局变量和函数实际上是window对象的属性和方法。
// 公认是JavaScript遗留的设计败笔,ES6就规定,let和const声明的变量和常量与window对象解绑
四、解构赋值
按照一定的模式,将数组或对象中的数据解构出来赋值给变量。
解构赋值的特征:
a) 必须要有赋值操作
b) 等号的后边是要解构的数组或对象
c)等号的前面是 模式和变量
4.1 数组解构赋值的几种情况
1)完全解构: 解构的数据和变量一一对应
2)不完全解构:解构的数据比变量多
3)不完全解构:解构的数据比变量少
4)不完全解构:缺省情况
5)解构赋值的默认值
4.2 对象解构赋值
1) 对象中的属性是没有次序,对象依靠键的匹配实现解构赋值
2)对象解构赋值的默认值:当解构失败或者严格等于undefined,默认值生效
let {name,age,sex,height=“180cm”}= {name:“zhangsan”,age:19,sex:“男”}
console.log( height );
4.3 函数形参的解构赋值
a) 利用数组解构赋值作为函数形参。适用于对参数的顺序有要求
b) 利用对象解构赋值作为函数形参。适用于对参数属性没有要求
c) 可以使用解构赋值默认值
五、应用场景
5.1 复杂结构(json)的解构赋值
5.2 交换变量的值
5.3 利用解构赋值获取函数的多个返回值
5.4 利用解构赋值实现ajax的封装函数
六、字符串扩展:模板字符串``
传统的字符串拼接非常繁琐并且不能保持html的结构。ES6引入模板字符串(``),它可以在其中加入任意结构的html代码,并且可以使用 ${} 在其中嵌入变量或表达式。
七、ES6对象扩展
7.1 对象的属性和方法可以简写
// 对象的键和变量重名的话可简写
// 对象中方法可简写
let uname = "zhangsan";
let obj = {
uname,
say(){
console.log(this.uname);
}
}
obj.say();
7.2 ES6支持对象的键为变量或表达式
let name = "姓名";
let age = 18;
let json = {
[name]:"张三",
age,
sex:"男"
}
json[name] = "李四";
案例:生成有规律的键的对象:
let arr = {};
for(let i=0;i<26;i++){
// console.log( String.fromCharCode(65+i) );
let str = String.fromCharCode(65+i);
arr[str] = [];
}
console.log( arr );
7.3 对象的合并 Object.assign()
let p1 = {name:"jack"};
let p2 = {age:18};
let p3 = {sex:"男"};
// 合并
Object.assign(p1,p2,p3);
console.log( p1 );
7.4 Object.keys() 和 Object.values() 将对象中所有的键或值转换为数组返回
console.log( Object.keys(p1) );
console.log( Object.values(p1) );
八、数组扩展
8.1 Array.from()
作用:将类数组对象转换为真正的数组。
类数组对象:html集合、nodelist、arguments
//类数组对象结构:
let obj1 = {
"0":"hello",
"1":"ok",
"2":"world",
length:3
}
// Array.from() 将类数组对象转换为真正的数组
let arr1 = Array.from( obj1 );
console.log( obj1 );
console.log( arr1 );
8.2 includes()
作用:查找数组中是否有指定的值,返回boolean。
let arr = [2,3,NaN,4];
if( arr.indexOf(NaN) != -1){
console.log("找到了");
}else{
console.log("没找到");
}
if( arr.includes(NaN) ){
console.log("找到了");
}else{
console.log("没找到");
}
九、函数扩展
9.1 箭头函数
ES6允许使用箭头声明函数,作用简化代码。
以箭头(=>)为界:
箭头的后边(函数体):
1) 如果有多条代码,必须用大括号包起来
2) 如果只有一条代码,大括号可省略。
3) 如果只有一条代码,而且是return 语句,return 也可省略
箭头的前面:
1) 如果只有一个形参,圆括号可省略
2)如果没有形参或者有多个形参,则必须用圆括号包起来
特殊情况:如果函数内只有一条语句,而且是返回一个对象,为了避免歧义,需要使用圆括号包起来
var fn2 = (x,y)=>({x,y})
9.2 箭头函数中的this指向规律
ES5中this指向规律:
1) 在全局中指向window,定时器中指向window
2) 在事件处理函数中的this指向事件源
3) 在对象的方法中的this指向对象本身
4)call() / apply() / bind() 可以改变this指向
ES6中this指向规律:
1)当定义好箭头函数后,其中this指向就确定了,与事件绑定、call\apply 等没有关系
2)永远指向其上层环境(环境指的是函数内或全局,只有这两种情况,其他的大括号不能称为环境)
小经验:找最近的大括号,看能不能console.log(this),如果能,this指向谁箭头函数中的this也指向谁,如果不能,继续向上找大括号,一直到全局下。
let obj = {
title:"张三",
op:{
title:"jack",
say(){
console.log(this);
return {
play:()=>{
console.log("我是"+this.title);
}
}
}
}
}
let oo = obj.op.say()
oo.play();
箭头函数不适用的情况:
1) 事件处理函数中
2) 不能作为构造函数使用
9.3 函数形参的默认值
// ES5为函数形参指定默认值
/* function fn(name){
name = name||"张三"; //短路语法
console.log( name );
}
fn(); */
// ES6 直接在声明形参时指定默认值
function fn(name="张三"){
console.log(name);
}
fn("胡宁宁");
十、 rest 剩余参数运算符 (…)
剩余参数运算符只出现函数声明形参时。作用:获取函数的多余实参。
// rest剩余参数运算符,获取多余实参放到一个数组中
// 和 arguments 功能类似,但使用更方便。arguments在箭头函数中无法使用
// 注意: rest参数必须放最后一位
function fn(a,...b){
console.log( arguments );
console.log( c );
}
fn(1,2,3,4,5)
十一、 spread 扩展运算符 ( … )
作用:像rest的逆运算,将数组转换为逗号分隔的参数列表
let arr = [2,3,4,5];
console.log( ...arr );
// 复制 或 合并 数组
let arr2 = [...arr];
arr.push(6);
console.log( arr, arr2 );
let arr3 = [...arr,...arr2];
console.log( arr3 );
// 合并对象
let p1 = {name:"jack"};
let p2 = {sex:"男"};
let p3 = {
...p1,
...p2
}
console.log( p3 );
// 为函数传参
console.log( Math.min(...arr) );
十二、Symbol类型
已知的JavaScript中数据类型:String,Number, boolean,undefined, null, Object, symbol
作用:创建一个独一无二的值,保证不会和别的重复。
// symbol()中的参数,类型代码中的注释,对symbol类型没有任何影响,只起到区分的作用。
let s1 = Symbol("老大");
let s2 = Symbol("老二");
let s3= Symbol();
console.log( typeof s1 );
console.log( s1,s2 );//永远是false
// 作用:可以用于对象的键名,就得到一个永不会重复的键,避免被无意中覆盖。
let obj = {
[s1]:"顾小智",
[s2]:"周乾"
}
console.log( obj );
十三、 set 数据类型
set 是ES6新增的一种类似数组的数据结构。特征:set中的成员是唯一的,不能重复。作用:去除数组中重复的项。
// set类型,成员唯一的
let arr = [1,2,3,2,1,4];
let s1 = new Set(arr);
console.log( s1 );
// set类型的属性和方法:
// size:返回set中成员的个数
// add(): 添加某个值
// delete(): 删除某个值
// has(): 判断是否有某个成员
// clear(): 清除所有成员
s1.add(1);
console.log( [...s1] );
十四、map 数据类型
map 是ES6 新增的类似对象的数据结构。map也是键值对的集合,但是 map的“键”可以是任意类型(包括数组、对象等)。
// map类型,“键”可以是任何数据类型
/* let name = "姓名";
let obj = {
[name]:"zhangsan"
} */
let arr = ["ok","hello"];
let lis = document.getElementsByTagName("li");
let map1 = new Map();
map1.set(arr,"数组");
map1.set(lis,"所有li标签");
console.log( map1 );
按理说map比 json 功能强大,但是目前的开发环境下用处很少,原因目前流行前后端分离开发模式中,主要使用json来作为前后端交流的数据载体,而且 JSON.parse() , JSON.stringlfy() 可很方便的实现字符串与json对象的互转,但map目前不支持这两个方法。