ES6
1、let声明变量
- 块级作用域
- 不允许有重复声明
- 变量提升没有
暂存性死区 - 不与顶层对象挂钩
2、const声明常量
- 常量
- 不能重复定义
- 块级
- 声明不提升
- 不与顶层对象挂钩
- Object.freeze()冻结对象属性
3、变量解构赋值
解构赋值,就是快速的从对象或者数组或字符串中取出成员的一个语法方式
解构对象
快速的从对象中获取成员
// ES5的方法向得到对象中的成员
const obj = {
name: 'kerwin' ,
age: 100,
gender: '男'
}
let name = obj.name
let age = obj.age
let gender = obj.gender
//解构赋值的方式从对象中获取成员
const obj = {
name: 'kerwin',
age: '100',
gender: '男'
}
let {name,age,gender}=obj;
4、字符串与数值扩展
(1)字符串扩展
- includes函数
判断字符串中是否存在指定字符
let myname = "kerwin"
console.log(myname . includes("e")) //true
console.log (myname . startswith("k")) //true
console.log(myname . endswith("n")) //true
- repeat函数
repeat()方法返回一个新字符串,表示将原字符串重复n次。
let myname = "kerwin"
、
console.log(myname. repeat(3)) //kerwinkerwinkerwin
console.log(myname . repeat(0)) //""
console.log (myname . repeat(3.5)) //kerwinkerwinkerwin
console.log(myname . repeat("3"))//kerwinkerwinkerwin
(2)数值扩展
- 二进制和八进制表示法
let count1 = 100
let count2 = 0x100
let count3 = 0o100
let count4 = 0b100
- isFinite与isNaN方法
减少全局性方法,使得语言逐步模块化
let num1 = Number. isFinite(100) //true
let num2 = Number. isFinite(100/0) //false
let num3 = Number. isFinite(Infinity) // false
let num4 = Number. isFinite("100") //false
let num1 = Number. isNaN(100) // false
let num2 = Number. isNaN(NaN) //true
let num3 = Number . isNaN("kerwin") //false
let num4 = Number. isNaN("100") // false
它们与传统的全局方法isFinite()和isNaN()的区别在于,传统方法先调用Number()将非数值的值转为数值,再进行判断,而这两个新方法只对数值有效,Number.isFinite()对于非数值一 律返回false,Number.isNaN)只有对于NaN才返回true,非NaN一律返回false。
- isinteger方法
用来判断一个数值是否为整数。
let num1 = Number. isInteger(100) //true
let num2 = Number. isInteger(100.0) //true
let num3 = Number. isInteger("kerwin") //false
let num4 = Number . isInteger("100") //false
- 极小常量Number.EPSILON
它表示1与大于1的最小浮点数之间的差。2.220446049250313e-16
function isEqual(a,b){
return Math.abs(a-b)<Number . EPSILON
}
console.log(isEqual(0.1+0.2,0.3)) //true
console.log(0.1+0.2===0.3) //false
- Math.trunc
将小数部分抹掉,返回一个整数。
console.log(Math. trunc(1.2)) //1
console.log(Math. trunc(1.8)) //1
console.log(Math. trunc(-1.8)) //-1
console.log(Math.trunc(-1.2)) //-1
- Math.sign
Math. sign方法用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值。
Math. sign(-100) // -1
Math. sign(100) // +1
Math. sign(0) // +0
Math. sign(-0) // -0
Math. sign("kerwin") // NaN
5、数组扩展
- 扩展运算符
let arr1 = [1,2,3]
let arr2 = [4,5,6]
console.log([...arrl,...arr2])
- Array.from
将类数组对象转换为真正数组
function test(){
console.log(Array. from(arguments))
}
test(1,2,3)
let oli = document. queryselectorAll("li")console.log(Array. from(oli))
- Array.of
将一组值转化为数组,即新建数组
let arr1 = Array(3)
console.log(arr1)// [,,]
let arr2 = Array.of(3)console.log(arr2)// [3]
- find方法
1)该方法主要应用于查找第一个符合条件的数组元素
2)它的参数是一个回调函数。 在回调函数中可以写你要查找元素的条件当条件成立为true时,返回该元素。如果没有符合条件的元素,返回值为undefined - findIndex()
- findLast findLastIndex() ES2022
- fill
- flat() flatMap() 扁平化
6、对象扩展
- 对象简写
- 对象属性 表达式
- 扩展运算符… ES2018
- Object.assign
- Object.is 判断是否相等
7、函数的扩展
- 参数默认值
- rest参数 剩余参数
- name属性
- 箭头函数:写法简介
()=>{}
(1)只有return 可以省略
(2)如果返回对象需要注意
(3)如果只有一个参数,可以省略()
(4)无法访问arguments,无法new
(5)箭头没有this,this指向父作用域
8、Symbol
ES6引入了一种新的原始数据类型 symbol,表示独一无二的值。它属于JavaScript语言的原生数据类型之一,其他数据类型是:undefined、 null、 布尔值(Boolean) 、字符串(String) 、数值(Number)、对象 (Object) 。
- 使用Symbol作为对象属性名
let name = Symbol()//生成了一个symbol类型数据
let age = Symbol()
var obj ={
[name]:"kerwin",
[age] :100
}
- Symbol()函数可以接受一个字符串作为参数,表示对Symbol实例的描述。这主要是为了在控制台显示,比较容易区分。
let name = Symbol("name ")
let age = Symbo1("age")
var obj={
[name]: "kerwin",
[age] :100
}
console.log(obj)
- Symbol.for()可以重新使用同一个Symbol值
var obj ={
[symbol. for("name ")]: "kerwin",
[symbol. for("age ")]:100
}
console.log(obj[symbol.for("name")])
注:
- 不能进行运算
- 显示调用toString()
- 隐式转换boolean
9、Iterator迭代器
Iterator的作用有三个:
一是为各种数据结构, 提供一个统一的、 简便的访问接口;
二是使得数据结构的成员能够按某种次序排列;
三是ES6创造了一种新的遍历命令for…of循环,lterator 接口主要供for…of循环
let arr = ["kerwin", "tiechui", "gangdaner"]
for(let i of arr){
console.log(i)
}
Iterator的遍历过程是这样的。
(1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
(2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
(3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
(4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。
let i = arr[symbol. iterator]()
console.log(i. next())
console.log(i. next())
console.log(i. next())
console.log(i. next())
ES6规定,默认的Iterator接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是"可遍历的”(iterable)。Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。
原生默认具备Iterator接口的数据结构如下。
- Array
- Set
- Map
- String
- arguments对象.
- NodeList对象
如何对于对象进行for fo遍历?
let obj ={
0: "kerwin",
1: "tiechui",
2: "gangdaner",
length: 3,
[Symbol.iterator]: Array.prototype[Symbol.iterator]
}
for(let i of obj) {
console.log(i)
}
let obj2 = {
data: ['kerwin', 'tiechuiI, "gangdaner"],
[Symbol. iterator](){
//let _this=this
let index=0;
return {
next:()=>{
if (index < this. data.1ength)
return {
value: this. data[index++],
done: false
}
}else{
return {
value: undefined,
done: true
}
}
}
}
}
for (let i of obj2) {
console. log(i)
}
10、Set结构
它类似于数组,但成员的值都是唯一的, 没有重复的值。
(1).初识Set
let s1 = new Set([1, 2,3, 2,3])
console. log(s1)
let s2 = new Set()
s2. add(1)
s2. add(2)
s2. add(3)
console.log(s2)
(2).实例的属性和方法
- size: 返回Set实例的成员总数。
- Set. prototype. add(value):添加某个value。
- Set. prototype. delete (va1ue):删除某个value,返回一个布尔值,表示删除是否成功。
- Set. prototype. has(value) :返回一个布尔值,表示该值是否为set的成员。
- Set. prototype. clear():清除所有成员,没有返回值。
(3).遍历
- Set. prototype. keys() :返回键名的遍历器
- Set. prototype. values() :返回键值的遍历器
- Set. prototype. entries() :返回键值对的遍历器
- Set. prototype. forEach()):遍历每个成员
11、Map结构
类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
(1)初识Map
let m1 = new Map()
m1.set("name", "kerwin")
m1.set({a:1},"大连")
console. 1og(m1)
let m2= new Map([
["name","kerwin"],
[{a:1},"大连"]
])
console.log(m2)
(2)实例的属性和方法
- size:返回Map结构的成员总数。
- Map. prototype . set(key,value) :添加key对应得value, 返回Map结构本身。
- Map. prototype . get(key) :获取key对应的value
- Map. prototype. delete(key) :删除某个键(键名+键值)
- Map. prototype . has(key) :某个键是否在当前Map对象之中。
- Map.prototype.keys(): 返回键名的遍历器。
- Map.prototype.values():返回键值的遍历器。
- Map.prototype.entries():返回所有成员的遍历器
- Map.prototype.forEach():遍历Map的所有成员
12、Proxy代理
Proxy如其名,它的作用是在对象和和对象的属性值之间设置一个代理,获取该对象的值或者设置该对象的值,以及实例化等等多种操作,都会被拦截住, 经过这一层我们可以统一处理, 我们可以认为它就是"代理器"
- get方法
let target = {}
let proxy = new Proxy(target,{
get(target, prop){
return target[prop]
}
})
- set方法
Proxy本质上属于元编程非破坏性数据劫持,在原对象的基础上进行了功能的衍生而不影响原对象,符合松耦合高内聚的设计理念
13、Reflect对象
Reflect可以用于获取目标对象的行为,它与Object类似,但是更易读,为操作对象提供了一种更优雅的方式。它的方法与Proxy是对应的。
(1)代替Object的某些方法
const obj = {
};
Reflect. defineProperty(obj, 'name', {
value: 'kerwin',
writable: false ,
configurable:fa1se
});
(2)修改某些Object方法返回結果
//老写法
try {
Object. defineProperty(target, property, attributes);
// success
} catch (e) {
// fail
}
//新写法
if (Reflect. defineProperty(target, property, attributes)) {
// success
} e1se {
// fail
}
(3)命令式变为函数行为
const obj = {
name : "kerwin"
};
//老写法
console.log("name" in obj) //true
//新写法
console.log(Reflect. has(obj,'name')) //true
//老写法
delete obj . name
//新写法
Reflect. deleteProperty(obj, "name")
(4)配合Proxy
let target = new Set()
const proxy = new Proxy(target, {
get(target, key) {
const value = Reflect . get(target ,key)
// 遇到Function都手动绑定一下this
if (value instanceof Function) {
console.log(`访问${value}方法了`)
return value. bind(target)
//不能 是 call apply
}
return value
},
set() {
return Reflect. set(...arguments)
}
})
proxy. add(1)
let arr=[1,2,3]
let proxy = new Proxy(arr,{
get(target, key) {
console.log('get', key)
return Reflect. get(...arguments)
},
set(target, key, value) {
console. log('set', key, value)
return Reflect.set(...arguments)
}
})
proxy . push(4)
//能够打印出很多内容
//get push (寻找proxy.push 方法)
//get length (设置当前的length)
//set 3 4(设置proxy[3]=4)
//set length 4 (设置proxy. length = 4)
14、Promise
Promise 是异步编程的一种解决方案,比传统的解决方案回调函数,更合理和更强大。ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
- 指定回调函数方式更灵活易懂。
- 解决异步回调地狱的问题。
Promise.all
Promise.race
(1)回调地狱
- 当一个回调函数嵌套一个回调函数的时候
- 就会出现一个嵌套结构
- 当嵌套的多了就会出现回调地狱的情况
- 比如我们发送三个ajax请求
第一个正常发送
第二个请求需要第一个请求的结果中的某一个值作为参数。
第三个请求需要第二个请求的结果中的某一个值作为参数 - 回调地狱,其实就是回调函数嵌套过多导致的
- 当代码成为这个结构以后,已经没有维护的可能了
(2)Promise使用
语法:
new Promise(function (resolve, reject) {
// resolve表示成功的回调
// reject表示失败的回调
}). then(function (res) {
//成功的函数
}). catch(function (err) {
// 失败的函数
})
(3)Promise对象的状态
Promise对象通过自身的状态,来控制异步操作。Promise 实例具有三种状态。
异步操作未完成(pending)
异步操作成功(fulfilled)
异步操作失败(rejected)
这三种的状态的变化途径只有两种。
从“未完成”到“成功”
从“未完成”到“失败”
一旦状态发生变化, 就凝固了,不会再有新的状态变化。这也是Promise这个名字的由来,它的英语意思是“承诺”,一旦承诺成效,就不得再改变了。这也意味着,Promise 实例的状态变化只可能发生一次。
因此,Promise 的最终结果只有两种。
异步操作成功,Promise 实例传回一个值(value),状态变为fulfilled.
异步操作失败,Promise 实例抛出一个错误(error),状态变为rejected。
15、Generator函数
Generator函数是ES6提供的一种异步编程解决方案
Generator函数是一个状态机, 封装了多个内部状态。
执行Generator函数会返回一个遍历器对象,也就是说,Generator函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历Generator函数内部的每一个状态。
(1)基本语法
function *gen(){
console. log(1)
yield;
console. log(2)
yield;
console. log(3)
}
let g = gen()
g.next()
g.next()
g.next()
yield(产出)表达式是暂停执行的标记,而next方法可以恢复执行。
(2)异步流程
手动版本
function *gen() {
let res1 = yield ajax("1. json")
console.log(res1)
let res2 = yield ajax("2. json")
console.log(res2)
}
let g = gen()
g. next(). value. then(data=>{
g. next(data). value. then(data=>{
g. next(data)
})
})
自动版本
function* gen() {
let res1 = yie]d ajax("1. json")
console. log(res1)
let res2 = yie1d ajax("2. json")
console. log(res2)
}
function AutoRun(gen) {
let g = gen();
function next(data) {
let res = g.next(data);
if (res. done) return
res. value. then(function (data) {
next (data);
});
}
next();
}
AutoRun(gen) ;
16、Class语法
(1)类的写法
class Person{
constructor(name ,age){
this. name = name;
this.age = age;
}
sayOf(){
console.log(this. name , this. age)
}
}
let obj = new Person("kerwin" ,100)
console.log(obj)
(2) getter与setter
17、Module语法
模块化
异步加载
私密不漏
重名不怕
依赖不乱
18、NodeJS中的模块化
JavaScript现在有两种模块。一种是ES6模块,简称ESM;另一种是CommonJS模块,简称CJS
Common]S模块是Node.js专用的,与ES6模块不兼容。语法上面,两者最明显的差异是,CommonJS模块使用require()和module. exports , ES6模块使用import和export.
ES6模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入。
写法1:
export default A1
import a1 from "./1.js"
写法2:
export {A1,A2}
import {A1,A2} from "./1.js"
import {Al as a1,A2 as a2} from "./1.js"
import * as obj from "./1.js"