一、ES概述
1.1 什么是ECMA
ECMA(European Computer Manufactures Association)中文名称为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994年后该组织改名为Ecma国际。
1.2 什么是ECMAScript
ECMAScript是由Ecma国际通过ECMA-262标准化的脚本程序设计语言。
(ECMA-262是Ecma国际指定的众多标准之一,定义了ECMAScript语言规范,这个标准也叫ECMAScript语言规范,简称ES规范)
然而ES在万维网上广泛应用,往往被称为JavaScript或JScript,所以ES可以理解为是JavaScript的一个标准,但实际上JavaScript是ECMA-262标准的实现和扩展。
JavaScript通俗来说, 就是ECMAscript的方言
1.3 ES历史版本
版本 | 发表日期 | 与前版本的差异 |
---|---|---|
1 | 1997年6月 | 首版 |
2 | 1998年6月 | 格式修正,以使得其形式与ISO/IEC16262国际标准一致 |
3 | 1999年12月 | 强大的正则表达式,更好的词法作用域链处理,新的控制指令,异常处理,错误定义更加明确,数据输出的格式化及其它改变 |
4 | 放弃 | 由于关于语言的复杂性出现分歧,第4版本被放弃,其中的部分成为了第5版本及Harmony的基础;由ActionScript实现 |
ES5 | 2009年12月 | 新增“严格模式(strict mode)”,一个子集用作提供更彻底的错误检查,以避免结构出错。澄清了许多第3版本的模糊规范,并适应了与规范不一致的真实世界实现的行为。增加了部分新功能,如getters及setters,支持JSON以及在对象属性上更完整的反射 |
5.1 | 2011年6月 | ECMAScript标5.1版形式上完全一致于国际标准ISO/IEC 16262:2011。 |
ES6 | 2015年6月 | ECMAScript 2015(ES2015),第 6 版,最早被称作是 ECMAScript 6(ES6),添加了类和模块的语法,其他特性包括迭代器,Python风格的生成器和生成器表达式,箭头函数,二进制数据,静态类型数组,集合(maps,sets 和 weak maps),promise,reflection 和 proxies。作为最早的 ECMAScript Harmony 版本,也被叫做ES6 Harmony。 |
7 | 2016年6月 | ECMAScript 2016(ES2016),第 7 版,多个新的概念和语言特性 |
8 | 2017年6月 | ECMAScript 2017(ES2017),第 8 版,多个新的概念和语言特性 |
9 | 2018年6月 | ECMAScript 2018 (ES2018),第 9 版,包含了异步循环,生成器,新的正则表达式特性和 rest/spread 语法。 |
10 | 2019年6月 | ECMAScript 2019 (ES2019),第 10 版 |
11 | 2020年6月 | ECMAScript 2020 (ES2020),第 11 版 |
注:从ES6开始,每年发布一个版本
1.4 为什么要学习ES6
- ES6 的版本变动内容最多,具有里程碑意义
- ES6加入许多新的语法特性,编程实现更简单、高效
- ES6是前端发展趋势,就业必备技能
二、变量声明
2.1 let变量声明及其特性
2.1.1 变量不能重复声明
let变量不可以重复声明,var变量可以
//let重复声明
let color='red';
let color='red';
//报错:Identifier 'color' has already been declared
2.1.2 块级作用域
let变量只能在块作用域里访问,出了代码块无效;var没有块级作用域,能正确读取
注:{},if,else,while,for都能形成块级作用域
/* 2.块级作用域 */
{
let a='hello world';
}
console.log(a);
//报错: a is not defined
2.1.3 不存在变量提升
/* 3.变量提升 */
console.log(a);// undefined ===>a已声明还没赋值,默认得到undefined值
console.log(b);// 报错
var a=100;
let b=10;
2.1.4 不影响作用域链
作用域链
一般情况下,变量取值到 创建 这个变量 的函数的作用域中取值。
但是如果在当前作用域中没有查到值,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链。
{
let title='es6基础';
function fn(){
console.log(title);
}
fn();
}
2.2 const声明常量及其特点
- 一定要有默认初始值
- 一般常量使用大写(潜规则)
- 常量值不能修改
- 块级作用域
- 对于数组和对象的元素修改,不算对常量修改,不会报错
三、变量解构赋值
解构赋值:在ES6中允许一定模式从数组和对象中提取值,对变量进行赋值
3.1 数组的解构
//数组的解构
let [a,b,c]=[1,2,3];
console.log(a,b,c); ====>1,2,3
/* ,作为占位符 */
let arr=["小明","张三","李四","王五"];
let [,,,one]=arr;
console.log(arr);
console.log(one);======>王五
3.2 对象的解构
const zhao={
name:'赵本山',
age:'不详',
job:function(){
console.log("我是小品演员");
}
};
let {name,age,job}=zhao;
console.log(name,age,job);
job();
/* 不用写成zhao.job(); */
四、箭头函数
4.1 概念
箭头函数:箭头函数用来简化函数定义语法的,使用(=>)来定义函数。
写法:
//声明
let fn=(a,b)=>{
return a+b; //代码体
}
//调用
let result=fn(1,2);
console.log(result);====>3
4.2 特性
- 在箭头函数中this是静态的,始终指向函数声明时所在作用域下的值(call函数可以改变this指向,用call举例)
- 不能作为构造实例化对象,不能通过 new 关键字调用
- 不能使用arguments变量(arguments变量用来保存实参)
- 箭头函数的简写
1.当形参有且只有一个的时候,可以省略小括号
2.当代码体只有一条语句是,可以省略花括号此时return必须省略,而且语句的执行结果就是函数的返回值
五 扩展运算符
5.1 概念
【...】扩展运算符能将【数组】转化为逗号分隔的【参数序列】
const fruits=['apple','orange','pear'];
function eating(){
console.log(arguments);
}
eating(...fruits);====> 'apple','orange','pear'
eating(fruits);=======>['apple','orange','pear']
5.2 应用
//1.数组的合并
const fruits=['apple','orange','pear'];
const food=['noodles','rice'];
const all=[...food,...fruits];
console.log(all);====>['noodles', 'rice', 'apple', 'orange', 'pear']
//2.数组的克隆
const like=[...fruits];
console.log(like);===>['apple', 'orange', 'pear']
//3.将伪数组转化为真正的数组
const divs=document.querySelectorAll('div')//假设有三个div盒子
const divArr=[...divs];
console.log(divArr);====>[div,div,div]
六 函数传参
6.1 形参初始值 具有默认值的参数,一般位置要靠后
function add(a,b,c=10){
return a+b+c;
}
console.log(add(1,2));//13
console.log(add(1,2,3));//6
6.2 与解构赋值结合
function connect({username,password,host}){
console.log(username);
console.log(password);
console.log(host);
}
connect({
username: 'zhao',
password:222,
host:'localhost'
})
6.3 rest参数 ...args
ES6引入rest参数,用于获取函数的实参,用来代替arguments去接受多个参数
在ES5中使用arguments得到的是对象,而rest得到的是数组
对于扩展运算符,rest参数把很多参数整合成一个数组,扩展运算符则是遍历对象展开成为一个参数序列
!!rest参数必须放到参数最后
function data(){
console.log(arguments); ====>object
}
data('1','2','3');
/* rest参数 */
function data(...args){
console.log(args);===>array
}
七 数组新特性
7.1 Array.from()
此方法可将数组或可遍历对象转化为真正的数组
let arrayLike={
'0':1,
'1':2,
'2':3,
length:3
}
let arr=Array.from(arrayLike);
console.log(arr);=====> [1, 2, 3]
此外,Array.from还可以接受第二个参数(是个函数),用来对每个元素进行处理,将出来的值放入返回的数组。
let arr=Array.from(arrayLike,item=>item*2);
console.log(arr);====>[2, 4, 6]
7.2 find()
find()方法用于找出第一个符合条件的数组成员并返回其值,如果没有找到返回undefined
arr.find(function(element,index,array){})
- element:指定数组中每一项元素的值
- index:指定数组中每一项元素的索引值
array
:指定数组本身
let arr=[{
id:1,
name:'张三'
},
{
id:2,
name:'李四'
}];
let owner=arr.find(element=>element.id==2);
console.log(owner);======>{id: 2, name: '李四'}
7.3 findIndex()
用于找出第一个符合条件的数组成员的位置,如果没有找到返回-1
和find()方法的格式一样
let arr=[1,4,6,2,5];
let index=arr.findIndex((element,index)=>element>5);
console.log(index);======>2
7.4 includes()
表示某个数组是否包含给定的值,返回布尔值
arr.includes(searchElement, fromlndex);
searchElement
:需要查找的元素值。fromlndex
:可选项,从该索引处开始查找searchElement。如果为负值,则按升序从倒数第几个开始搜索。默认为0。
let result=[1,2,3].includes(2);
console.log(result);//true
let result2=[1,2,3].includes(4);
console.log(result2);//false
八 字符串新特性
8.1 模板字符串
ES6新增的创建字符串的方式,使用反引号定义
let name=`字符串新定义`;
模板字符串特点
1.模板字符串可以解析变量
let name=`zhangsan`;
let sayHello=`Hello,my name is `+name;
let sayHello2=`Hello,my name is ${name}`
console.log(sayHello2);
2.模板字符串可以换行
3.在模板字符串中可以调用函数
const fn=()=>{
return`我是fn函数`;
}
let html = `我是模板字符串 ${fn()}`;
console.log(html);//我是模板字符串 我是fn函数
8.2 startsWith()和endsWith()
- startswith():表示参数字符串知否在原字符串的头部,返回布尔值
- endswith():表示参数字符串知否在原字符串的尾部,返回布尔值
let str=`hello world`;
console.log(str.startsWith('hello'));//true
console.log(str.endsWith('world'));//true
8.3 repeat()
repeat方法表示将原字符串重复n次,返回一个新字符串
console.log('x'.repeat(3));//xxx
console.log('hello'.repeat(4));//hellohellohellohello
九 ES6中的面向对象
9.1 ES6中的类和对象
1. 对象:对象是一组无序的相关属性和方法的集合,所有事物都是对象,例如字符串、数值、数组、函数等。
对象的组成:
- 属性:事物的特点,在对象中用属性来表示
- 方法:事物的行为,在对象中用方法来表示
2. 类class
ES6中新增了类的概念,可以使用class关键字声明一个类,之后以这个类来实例化对象的。
类抽象了对象的公共部分,它泛指一个大类(class)
对象特指某一个,通过实例化一个具体的对象。
3.面向对象的思维特点
(1)抽取(抽象)对象共用的属性和行为组织(封装)成一个类(模板)
(2)对类进行实例化,获取类的对象
(汽车设计图纸就是一个类,一辆真实的宝马就是对象的实例)
4. 创建类
语法:
class name{
//class body
}
创建实例:类必须使用new实例化对象!
var xx=new name();
5. 类constructor构造函数
constructor()
方法是类的构造函数(默认方法),用于传递参数,返回实例对象,通过new命令生成对象实例时,自动调用该方法。如果没有显示定义,类内部会自动给我们创建一个constructor()。
类的共有属性放到constructor里面
6.添加类的方法
(1) 类里面所有函数不需要写function
(2)多个函数方法之间不需要逗号
9.2 类的继承
子类可以继承父类的一些属性和方法
1、extends关键字
class Father { //创建父类
}
class Son extends Father { //子类继承父类
}
2. super关键字
super关键字用于访问和调用对象父类上的函数。
class Son extends Father {
constructor(x,y){
super(x,y);//调用父类中的构造函数,将x,y作为参数传给父类constructor中
}
}
除了可以调用父类的构造函数,还可以调用父类的普通函数。
super.function() //调用父类中的普通函数function
class Father {
say() {
return '我是father';
}
}
class Son extends Father {
say() {
console.log(super.say() + '的son');
}
}
var son = new Son();
son.say(); //我是father的son
子类继承父类的方法同时扩展自己方法时,利用super() 调用父类的构造函数,super 必须在子类this之前调用
class Father {
constructor(x, y) {
this.x = x;
this.y = y;
}
sum() { //父类的加法运算
console.log(this.x + this.y);
}
}
// 子类继承父类的加法,同时想扩展减法
class Son extends Father {
constructor(x, y) {
super(x, y); !!!!!!super在this之前
this.x = x;
this.y = y;
}
substract() { //扩展减法
console.log(this.x - this.y);
}
}
var son = new Son(5, 3);
son.substract();//2
son.sum();//8
继承中的属性或者方法的就近原则:
1、继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的
2、如果子类没有,就去查找父类有没有这个方法,如果有。则执行父类的方法
9.3 使用类的注意事项
- 类里面共有的属性和方法一定要加this使用
- 在ES6中,类没有变量提升,所以必须先定义类,才能通过类实例化对象
- this的指向
- constructor里面的this指向实例对象
- 方法里面的this指向这个方法的调用者
十 ES6模块化
10.1 ES6 模块化语法
模块功能主要由两个命令构成:
- export 命令用于规定模块的对外接口
- import命令用于输入其他模块提供的功能
10.2 模块暴露数据语法
(1)分别暴露,每一个前面都加export
(2)统一暴露
export{ };
(3)默认暴露
export default{
}
多了一层default结构,调用时必须写上default
m3.default.sayhello(); //hello
10.3 引入模块数据语法
(1)通用的导入方式
import * as name from "resource";
import * as m3 from "./m.js";
(2) 解构赋值形式
import {name,sayhello} from "./m.js"; //分别暴露时
import {name as name2,sayhello as sayhello2} from "./m2.js";
//统一暴露,重名时必须改名
import {default as m3} from "./m3.js"; //默认暴露,必须将default改名
(3)简便形式(只针对默认暴露)
import m3 from "./m.js";//没有*,也没有花括号
10.4 入口文件
除了在html文件的script标签中引入模块数据以外,还可以做一个入口文件
十一 promise
11.1 定义
1、Promise,译为承诺,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强大
2、状态:pending(进行中)、fulfilled(已成功)、rejected(已失败)
11.2 优点
- 链式操作减低了编码难度
- 代码可读性明显增强
11.3 特点
对象的状态不受外界影响,只有异步操作的结果,可以决定当前是哪一种状态
一旦状态改变(从pending变为fulfilled和从pending变为rejected),就不会再变,任何时候都可以得到这个结果
11.4 用法
1、Promise对象是一个构造函数,用来生成Promise实例:
const promise = new Promise(function(resolve, reject) {});
2、Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject:
resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”
reject函数的作用是,将Promise对象的状态从“未完成”变为“失败
3、实例方法:Promise构建出来的实例存在以下方法
then():then是实例状态发生改变时的回调函数,第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数
catch():catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数
finally():finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作
4、构造函数方法:Promise构造函数存在以下方法
all():Promise.all()方法用于将多个 Promise实例,包装成一个新的 Promise实例
race():Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实
allSettled():Promise.allSettled()方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例
resolve():将现有对象转为 Promise对象
reject():Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected
11.5 使用场景
- 将图片的加载写成一个Promise,一旦加载完成,Promise的状态就发生变化
- 通过链式操作,将多个渲染数据分别给个then,让其各司其职。或当下个异步请求依赖上个请求结果的时候,我们也能够通过链式操作友好解决问题
- 通过all()实现多个请求合并在一起,汇总所有请求结果,只需设置一个loading即可
- 通过race可以设置图片请求超时
https://blog.csdn.net/qq_34645412/article/details/81170576
十二 generator
12.1 定义
1、Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同
2、执行 Generator 函数会返回一个遍历器对象,可以依次遍历 Generator 函数内部的每一个状态
12.2 特征
1、function关键字与函数名之间有一个星号
2、函数体内部使用yield表达式,定义不同的内部状态
12.3 异步解决方案
1、回调函数:所谓回调函数,就是把任务的第二段单独写在一个函数里面,等到重新执行这个任务的时候,再调用这个函数
2、Promise:Promise就是为了解决回调地狱而产生的,将回调函数的嵌套,改成链式调用
3、generator:yield表达式可以暂停函数执行,next方法用于恢复函数执行,这使得Generator函数非常适合将异步任务同步化
4、async/await:将上面Generator函数改成async/await形式,更为简洁,语义化更强了
5、区别:
- promise和async/await是专门用于处理异步操作的
- Generator并不是为异步而设计出来的,它还有其他功能(对象迭代、控制输出、部署Interator接口...)
- promise编写代码相比Generator、async更为复杂化,且可读性也稍差
- Generator、async需要与promise对象搭配处理异步情况
- async实质是Generator的语法糖,相当于会自动执行Generator函数
- async使用上更为简洁,将异步代码以同步的形式进行编写,是处理异步编程的最终方案
https://blog.csdn.net/weixin_43638968/article/details/105475881