1.es简介
术语ECMAScript和我们平时表达的JavaScript实际是一个意思,在日常场合可以互换,ECMA组织(前身为欧洲计算机制造商协会)来制定和发布的脚本语言的规范。1997年ECMA发布 262 号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为 ECMAScript,这个版本就是 1.0 版。
ES的几个重要版本
ES5 : 09年发布(我们之前学的是ES5)
ES6(ES2015) : 15年发布, 也称为ECMA2015
ES7(ES2016) : 16年发布, 也称为ECMA2016 (变化不大)
注:平时说ES6,一般是指ES2015标准,但是有时也是泛指“下一代JavaScript语言”
参考网址:https://es6.ruanyifeng.com/
2 let const
这两个关键字与var类似,都是用来声明一个变量
2.1 let
let用来声明变量,具有块级作用域、不能重复声明、不会预处理,不存在提升
2.2 const
const用来定义一个常量,即不变的值,定义后不能修改,其他特点与let相同
3.变量的解构赋值
从对象或者数组中提取数据,并赋值给变量(多个)
3.1对象的解构赋值
const obj = {
name: 'Rose',
age: 18,
sex: 'nv'
}
let {
name,
age,
sex
} = obj;
/* let name = obj.name;
let age = obj.age;
let sex = obj.sex; */
console.log(name, age, sex);
3.2数组的解构赋值(不常用)
let arr = [12, 'aa', null, undefined, obj];
/* let [a, b, c, d, f] = arr;
console.log(a, b, c, d, f); */
let [, , a] = arr; //这里面的数值可以是任意字母,字符串,但是不可以为数字,取得是对应下标的值,若是不想去前面的值,指向去第三个可以这样写let [,, c] = arr
console.log(a);
3.3 常见应用
给多个形参赋值
/* function fun(obj) {
console.log(obj.name, obj.age)
} */
function fun({
name,
age
}) {
console.log(name, age);
}
fun(obj);
4.模板字符串
简化字符串的拼接, 模板字符串必须用 `` 包含, 变化的部分使用${xxx}定义
5.对象的简写方式
对象的简写方式是省略同名的属性值,省略方法的function
let name = 'Tom';
let age = 18;
// let obj = {
// name:name,
// age:age,
// running:function(){
// console.log('running');
// }
// }
let obj = {
name,
age,
running(){
console.log('running');
}
}
console.log(obj);
6.三点运算符
6.1数组扩展运算符(三点运算符)
主要用于展开数组。
let arr = [1, 2, 3];
let arr1 = [4, 5, 6];
// console.log(...arr1);
/* arr.push(arr1); //[1,2,3,4,5,6]
console.log(arr); */
/* arr.push(...arr1);
console.log(arr); */
6.2 rest(可变)参数
用来取代arguments 但比arguments灵活,只能是最后部分形参参数
function foo(a, ...value) {
console.log(value);
console.log(arguments);
}
foo(1, 2, 3);
7.形参默认值
// 形参默认值 当不传入参数时,默认使用形参里面的默认值
function Foo(x=1,y=2){
this.x = x;
this.y = y;
}
let foo1 = new Foo();
console.log(foo1);
let foo2 = new Foo(12,52);
console.log(foo2);
8.新增数据类型
数据类型
基本数据类型:number string Boolean undefined null symbol BigInt
引用数据类型 :object Function Date…
8.1 Symbol
symbol是es6新增的一种数据类型,值是唯一的,解决命名冲突的问题的
let obj = {
name: 'Tom',
age: 18
}
let symbol = Symbol();
console.log(typeof symbol);
console.log(symbol);
let symbol1 = Symbol();
console.log(Symbol == symbol1);//自己同自己都不相同
obj[symbol] = '123';
console.log(obj);
for (let i in obj) {
console.log(i);
}
8.2BigInt
BigInt是ES2020引入的一种新型数据类型,只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。
为了与 Number 类型区别,BigInt 类型的数据必须添加后缀n。
扩展:为何引入BigInt
JavaScript 所有数字都保存成 64 位浮点数,这给数值的表示带来了两大限制。一是数值的精度只能到 53 个二进制位(相当于 16 个十进制位),大于这个范围的整数,JavaScript 是无法精确表示的,这使得 JavaScript 不适合进行科学和金融方面的精确计算。二是大于或等于2的1024次方的数值,JavaScript 无法表示,会返回Infinity。
let a = 123n;
console.log(typeof a);
let b = 25n;
console.log(a + b);
console.log(a === 123);
console.log(-a); //BigInt可以使用-号,不能使用+号
// BigInt对象
console.log(BigInt(123)); //123n
console.log(BigInt('123')); //123n
console.log(BigInt(false)); //0n
console.log(BigInt(true)); //1n
// BigInt()构造函数必须有参数,而且参数必须可以正常转换的数值,否则报错,以下内容会报错
/* new BigInt()
console.log(BigInt(undefined));
console.log(BigInt(null));
console.log(BigInt('123n'));//符串123n无法解析成 Number 类型,所以会报错。
console.log(BigInt('abc')); */
// 参数是小数也会报错
/* console.log(BigInt(1.5))
console.log(BigInt('1.5')) */
// 转换规则
/* 可以使用Boolean()、Number()和String()这三个方法,将 BigInt 可以转为布尔值、数值和字符串类型。 */
console.log(Boolean(0n)) // false
console.log(Boolean(1n)) // true
console.log(Number(1n)) //1
console.log(String(1n)) //'1'
// 上面代码中,注意最后一个例子,转为字符串时后缀n会消失。
// 另外,取反运算符(!)也可以将 BigInt 转为布尔值。
console.log(!0n) //true
console.log(!1n)//false
9.箭头函数
箭头函数的作用:定义匿名函数
1.没有参数,小括号不能省略:()=>{}
2.当有一个参数时,小括号可以省略: a =>{
console.log(a);
}
3.当参数大于1个时,小括号不能省略 ()=>{}
4.当后面只有一条语句时,大括号可以省略 ,函数的返回值就是该条语句的值,当多条语句时必须写上{},当需要返回值时必须写return ()=> console.log(‘xxx’);
箭头函数的特点
1.简洁
2.箭头函数没有自己的this指向,指向它的外层函数的this指向。
3.箭头函数没有原型。
/* 箭头函数 :主要用来定义回调函数 */
btn.addEventListener('click', () => {
console.log('111');
console.log(this);
});
let fun = a => console.log(a);
fun(1);
扩展:
IIFE(Immediately-Invoked Function Expression 立即调用函数表达式)又称匿名函数自调用
作用是隐藏内部实现,不污染外部命名空间
(function (i) {
var a = 4
console.log(a + i);
})(3)
9.1语法
- 没有参数: () => console.log(‘xxxx’)
- 一个参数: i => i+2
- 大于一个参数: (i,j) => i+j
- 函数体不用大括号: 默认返回结果
- 函数体如果有多个语句, 需要用{}包围,若有需要返回的内容,需要手动返回
- 使用场景: 多用来定义回调函数
Eg
let fun = () => console.log(‘fun()’);
fun();
1) 如果没有参数 () 不能省略
let fun = () => console.log(‘fun()’);
fun();
2) 有一个参数 () 能省略
let fun1 = a => console.log(a);
fun1(‘fun1()’);
3)当有两个或者两个以上参数 () 不能省略
let fun2 = (a, b) => console.log(a, b);
fun2(‘fun2’, ‘()’)
4)当只有一条语句或者表达式的时候 {} 可以省略 自动返回当前语句或者表达式执行的结果, 当加上{} 需要手动返回想要的结果
let fun3 = (x, y) => {return x + y};
console.log(fun3(3, 2));
5)当有多条语句或者表达式的时候 {} 不可以省略
let fun4 = (x, y) => {
console.log(x, y)
return x + y;
};
console.log(fun4(25, 36));
box.addEventListener(‘click’, function () {})
9.2特点
1、简洁
2、箭头函数没有自己的this,箭头函数的this不是调用的时候决定的,而是在定义的时候处在的对象就是它的this
3、扩展理解: 箭头函数的this看外层的是否有函数,
如果有,外层函数的this就是内部箭头函数的this,
如果没有,则this是window。
4、箭头函数没有原型的。
10.Promise对象
Promise对象: 代表了未来某个时间段将要发生的事件(通常是一个异步操作)
有了promise对象, 可以将异步操作以同步的流程表达出来, 避免了层层嵌套的回调函数(俗称’回调地狱’)
ES6的Promise是一个构造函数, 用来生成promise实例 /'prɒmɪs/允许允诺
它具有三个状态:
pending: 初始化状态 /'pendɪŋ/ 即将发生的
fullfilled: 成功状态
rejected: 失败状态 /rɪˈdʒɛkt/排斥拒绝,过去分词 不合格
10.1使用的基本步骤
1)创建promise对象
let promise = new Promise((resolve, reject) => {
//初始化promise状态为 pending
//执行异步操作 /rɪ'zɒlv/ 决定
if(异步操作成功) {
resolve(value);//修改promise的状态为fullfilled
} else {
reject(errMsg);//修改promise的状态为rejected
}
})
2)成功状态调用promise的then()
promise.then(function(
result => console.log(result),
errorMsg => alert(errorMsg)
))
注:①成功和失败的顺序是不能改变的,由于是匿名函数,then()方法根据位置来给信息的,因而不能改变位置
②promise对象then方法有一个默认的返回值:promise实例对象,并且状态是成功状态,但是里面没有数据是undefined,当第二次调用promise时,若上一层的promise.then()为失败状态时,下一层的then()会调用默认值。
3)失败状态调用promise的catch()
promise.catch(err => {})
const promise = new Promise((resolve, reject) => {
//初始化状态
$.ajax({
type: 'get',
url: 'http://localhost:3000/play',
success: function (res) {
console.log(res);
resolve(res); //把初始化状态改变为成功状态
},
error: function (err) {
console.log(err);
reject(err); //把初始化状态改变为失败状态
}
})
})
promise.then((res) => {
console.log(res);
const promise1 = new Promise((resolve, reject) => {
$.ajax({
type: 'get',
url: 'http://localhost:3000/seckillFirst',
success: function (data) {
console.log(data);
resolve(data);
},
error: function (err) {
console.log(err);
reject(err);
}
})
})
return promise1;
})
.then((data) => {
console.log(data);
})
promise.catch((err) => {
console.log(err);
})
10.2关系图
11.async await
async函数(ES2016 是ES7中的)
真正意义上去解决异步回调的问题,同步流程表达异步操作,await后面必须跟异步操作
// 真正解决回调地狱问题的
const promise = new Promise((resolve, reject) => {
$.ajax({
type: 'get',
url: 'http://localhost:3000/play',
success: function (res) {
console.log(res);
resolve(res);
},
error: function (err) {
console.log(err);
reject(err);
}
})
});
(
async () => {
console.log('111');
let result = await promise; //await后面必须是promise对象
console.log(result);
}
)()
/* async function aa(){
let result = await promise;
console.log(result);
}
aa(); */
12. class类
class的使用方法:
1)通过class定义类/实现类的继承
2)在类中通过constructor定义构造方法
3)通过new来创建类的实例
4)通过extends来实现类的继承,super调用父类的构造方法(这两个方法需要结合使用)
/ɪk’stend; ek-/扩展,延伸的 /'suːpə; 'sjuː-/极好的
5)重写从父类中继承的一般方法
class Person {
// 调用类的方法
constructor(name, age) {
this.name = name;
this.age = age;
}
//定义一般的方法
running() {
console.log(this.name, this.age);
}
}
let person = new Person('lili', 18);
console.log(person);
person.running();
//定义一个子类
class SonPerson extends Person {
constructor(name, age, hobby) {
super(name, age); //调用了父类的构造方法
this.hobby = hobby;
}
jump() {
console.log(this.name, this.age, this.hobby);
}
}
let son = new SonPerson('xiaoming', 10, 'tiqiu');
console.log(son);
13.es6模块化语法
import / export
在浏览器或NodeJS环境中,是无法直接使用 import 语法的
在模块化的环境中每个JS文件都是一个独立的作用域,如果两个JS文件需要交互
那么,必须通过 导入和导出 才能实现
第一种语法:
导出:export default 要导出的内容
导入:import a from ‘模块路径’
注意:
1 使用 export default 导出的内容,在导入的时候,import后面的名称可以是任意的
2 在一个模块中 export default 语法只能使用一次
第二种语法:
导出: export const num = 888
导入: import { num } from ‘模块路径’
注意:
1 导入内容的时候,需要添加 {}
2 导入的内容(num),必须是模块导出的内容(num).如果导入内容与导出内容不相同,那么,导入内容为: undefined
3 export 不带 default 可以出现任意多次
给导入的变量起别名(解决命名冲突)
import { num as bNum } from ‘模块名称’
一次性全部导入一个模块中的内容
import * as bModule from ‘模块名称’
14.字符串扩展
1 .includes:判断是否包含某个字符串
2 .startsWith:判断是否以指定字符开头
3 .endsWith:判断是否以指定字符串结尾
4 .repeat:重复指定的次数 括号中填写次数
let str = 'abscddg';
console.log(str.includes('b'));
console.log(str.includes('o'));
console.log(str.startsWith('a'));
console.log(str.startsWith('b'));
console.log(str.endsWith('g'));
console.log(str.endsWith('n'));
console.log(str.repeat(5));
15.数值扩展
1 Number.isFinite是否有最大值
console.log(Number.isFinite(5));
console.log(Number.isFinite(NaN));
2 Number.isNaN()判断是否是NaN
console.log(Number.isNaN(NaN));
console.log(Number.isNaN(5));
3 Number.isInteger判断是否是整数
console.log(Number.isInteger(5.23));
console.log(Number.isInteger(5.0));
console.log(Number.isInteger(5));
4 Math.trunc()去除小数
console.log(Math.trunc(5.23));
16.数组扩展
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<script>
let btnArr = document.querySelectorAll('button');
console.log(btnArr);
let arr = [1,2,3];
console.log(arr);
// Array.from(伪数组) 将伪数组转变为真正的数组
console.log(Array.from(btnArr));
//Array.of()将一系列数值转变为数组
let arr1 = Array.of(1,'absd','12');
console.log(arr1);
//find 从前向后查找第一个出现符合条件的值
let arr2 = [1,5,9,8,6];
let result = arr2.find((item,index)=> item>5);
console.log(result);
//findIndex 从前向后查找第一个出现符合条件的值的下标
let result1 = arr2.findIndex((item,index)=>item>5);
console.log(result1);
17.对象扩展
1 Object.is()判断两个数据是否相等 返回值为布尔值
console.log(Object.is('abd','abd'));
console.log(NaN == NaN);
console.log(Object.is(NaN,NaN));
console.log(0 == -0);
console.log(Object.is(0,-0));
2 Object.assign(target,source1,source2…)将源对象上的属性复制到目标对象上
let obj1 = {name:'Tom',age:18};
let obj3 = {sex:'nan'}
let obj2 = {};
Object.assign(obj2,obj1,obj3);
console.log(obj2);
3 直接操作__proto__属性
let obj4 = {name:'Jerry',age:2};
let obj5 = {};
obj5.__proto__ = obj4;
console.log(obj5);
18.Set、Map容器
18.1set容器
1 Set 容器:存放不重复的value值,允许储存任何类型唯一值,无论原始/对象作用。
let set = new Set([1,1,2,3]);
2 set.size 长度
console.log(set,set.size);
3 向set容器中增加
set.add('abc');
console.log(set);
4 set.has 判断是否有某个value 返回值为布尔值
console.log(set.has(1));
console.log(set);
5 set.delete删除某个value
set.delete('abc');
console.log(set);
6 清空set容器
set.clear();
console.log(set);
18.2map容器
Map容器:无序的key 不重复的Key-value的集合。
let map = new Map([
['abc', 12],
['cde', 52]
]);
console.log(map);
设置值 set
map.set('sex', 'nan');
console.log(map);
取值 get
console.log(map.get('abc'));
删除 delete
map.delete('sex');
console.log(map);
判断是否拥有 has
console.log(map.has('abc'));
map遍历
map.forEach((item, index) => {
console.log(item, index);
})
清空
// map.clear();
console.log(map)
19.for of
1)遍历数组
let arr = [1,2,3,4];
for(let num of arr){
console.log(num);
}
2)遍历Set
let set = new Set([5,6,9]);
for(let num of set){
console.log(num);
}
3)遍历Map
let map = new Map([
['abc', 12],
['cde', 52]
]);
map.forEach((item, index) => {
console.log(item, index);
})
4)遍历字符串
let str = 'abdcefghi';
for(let i of str){
console.log(i);
}
5)遍历伪数组
// 1
let btnArr = document.querySelectorAll('button');
for(let btn of btnArr){
console.log(btn);
}
// 2
let map = new Map([['aa',12],['bb',58]]);
console.log(map);
for(let item of map){
console.log(item);
}