太原网站制作_太原网站建设_太原做网站_秘密武器开发者中心
历史搜索

最全ES6

游客2025-01-12 12:30:01
目录文章目录
  1. ES6
  2. 24. Generator
  3. ES7
  4. ES8
  5. ES9
  6. ES10
  7. ES11
  8. ES12
  9. 结语

最全ES6 1

let p = new Promise((resolve, reject) => {
    resolve(2)
    reject(1)
}).then(res => {
    console.log(res)
}).catcj(err => {
    console.log(err)
})
//只能输出 2,Promise 状态不能被改变

23.3 使用 Promise 发送 ajax 请求

单纯使用 ajax 需要嵌套非常多层。

使用 Promise 有大量重复代码,抽离出来写成一个函数,使得代码可读性更强,也有利于后期维护。

function getPromise(url) {
    return new Promise((resolve, reject) => {
        ajax(url, res => {
        	resolve(res)
    	})
    })
}
getPromise(...)
    .then(res => {
    console.log(res)
	return getPromise(...)
    }).then(res => {
        console.log(res)
        return getPromise(...)
    }).then(res => {
        console.log(res)
    })

统一捕获 err:

function getPromise(url) {
    return new Promise((resolve, reject) => {
        ajax(url, res => {
        	resolve(res)
    	})
    })
}
getPromise(...)
    .then(res => {
        console.log(res)
	return getPromise(...)
    }).then(res => {
        console.log(res)
        return getPromise(...)
    }).then(res => {
        console.log(res)
    }).catch(err => {
        console.log(err)
    })  //上述任何一个出现错误都会调用

23.4 Promise 的静态方法

Promise.resolve('success')

Promise.reject('fail')
function foo(flag) {
    if(flag) {
        return new Promise(resolve => {
            //异步操作
            resolve('success')
        })
    } else {
        return Promise.reject('fail')  //如果写成 return 'fail',当条件为 false 的时候,会报错
    }
}

foo(false).then(res => {
    console.log(res)  //fail
},err => {
    console.log(err)
})

Promise.all([...]) 所有对象都完成之后才会进入 res,只要有一个是失败的,都会进入 err 中

可应用于上传多张图片中

Promise.all([p1,p2,p3]).then(res => {
    console.log(res)}, err => {
    console.log(err)
})
const imgArr = ['1.jpg', '2.jpg', '3.jpg']
let promiseArr = []
imgArr.forEach(item => {
    promiseArr.push(new Promise((resolve, reject) => {
        // 图片上传的操作
        resolve()
    }))
})
Promise.all(promiseArr).then(res => {
    // 插入数据库的操作
    console.log('图片全部上传完成')
})

Promise.race([...]) 只要有一个成功,整个就会进入 res 中

可应用于请求图片超时

Promise.race([p1,p2,p3]).then(res => {
    console.log(res)}, err => {
    console.log(err)
})
function getImg() {
    return new Promise((resolve, reject) => {
        let img = new Image()
        img.onload = function () {
            resolve(img) //返回图片
        }
        // img.src = 'http://www.xxx.com/xx.jpg'
        img.src = 'https://www.imooc.com/static/img/index/logo.png'
    })
}

function timeout() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject('图片请求超时')
        }, 2000)
    })
}

Promise.race([getImg(), timeout()]).then(res => {
    console.log(res)
}).catch(err => {
    console.log(err)
}

24. Generator

function* foo() {
    for (let i = 0; i < 3; i++) { yield i } } let f = foo() console.log(f.next()) console.log(f.next()) console.log(f.next()) console.log(f.next()) //yield 关键字只存在于 Generator,这里的的 yield 关键字是在 forEach 函数里的 // function* gen(args) { // args.forEach(item => {
//         yield item + 1
//     })
// }
function* gen(x) {
    let y = 2 * (yield(x + 1))
    let z = yield(y / 3)
    return x + y + z
}
//在 next 里可以传递参数
let g = gen(5)
console.log(g.next()) // 6
console.log(g.next(12)) // y=24  8(对应的 x+1=12)
console.log(g.next(13)) // z=13 x=5 42(对应的 y/3=13

使用 Generator 进行 ajax 请求:

function request(url) {
    ajax(url, res => {
        getData.next(res)
    })
}

function* gen() {
    let res1 = yield request('static/a.json')
    console.log(res1)
    let res2 = yield request('static/b.json')
    console.log(res2)
    let res3 = yield request('static/c.json')
    console.log(res3)
}
let getData = gen()
getData.next()

25. Module

  • export default 默认,导入不需要知道命名(可以直接使用别名)
  • import * from ‘../../xx.js’

把庞大的代码拆开。

将多个功能的代码按功能进行分开,以达到多个模块组合在一起形成一个功能复杂的功能。

好处
  • 防止命名冲突
  • 代码复用
  • 高维护性
语法

<script type="module"> </script>

也可以使用 <script src="./src/js/app.js" type="module"></script> 将引用部分放到另一个 js 文件里

export 对外接口

导入的时候命名要完全一样,可以起别名,起了别名之后文件中使用只能使用别名,原名已经失效了

export 和 export default 可以一起使用 import add, {str} from '../../xxx.js'
分别暴露:在要暴露的语句前面+export。

统一暴露:在某个位置使用 export{},将要暴露的数据放在花括号里面。

在模块文件里,使用 export default

export default {

​ ...

}

这样就可以直接使用了。

默认暴露:export.default = { },这种方法在调用时需要添加default

导入不需要知道命名(可以直接使用别名)

  • import 输入其他模块提供的功能
    • 通用的导入方式:import * as m1 from “./src/js/m1.js”;

      导入的是全部

    • 解构赋值的形式:
      • import{school,teach} from “./src/js/m1.js”;
      • import{default as m1} from “./src/js/m1.js”;

      重名时需要使用别名,不然会报错

    • 简便形式(针对默认暴露):improt m3 from “./src/js/m3.js”
  • 使用 babel
    • 安装工具 npm i babel-cli babel-preset-env browerify -D
    • 编译: npx babel src/js -d dist/js --presets=babel-preset-env 先 [原文件目录] 后 [存放文件目录]
    • 打包 : npx browserify dist/js/app.js -o dist/bundle.js 将存放文件目录下的文件打包生成 bundle.js 文件

ES7

1. 数组拓展

  • Array.prototype.includes(searchElement[,fromIndex])
  • includes VS indexOf
    • includes 返回布尔值,可以检测 NaN
    • indexOf 返回 index / -1,不可以检测 NaN
  • 幂运算符:**等同于Math.pow()

ES8

1. 异步编程解决方案 Async Await

两者成对出现,代码可读性更强。

function timeout() {
    return new Promise(resolve => {
        setTimeout(() => {
            console.log(1)
            resolve()
        },1000)
    })
}

async function foo() {
    await timeout()   //等待 timeout()运行完毕后再继续往下运行
    console.log(2)
}

foo()

之前的 ajax 请求代码:

async function getData() {
    const res1 = await request('static/a.json')
    console.log(res1)
    const res2 = await request('static/b.json')
    console.log(res2)
    const res3 = await request('static/c.json')
    console.log(res3)
}

2. 对象拓展

  • Object.values() 获得值
  • Object.entries() 获得数组(key 和 value)
const res = Object,keys(obj).map(key => obj[key])
console.log(res)

//上面可以写成
console.log(Object.values(obj))
console.log(Object.entries(['a','b','c']))
//["0","a"],["1","b"],["2","c"]

3. 对象属性描述

  • Object.getOwnPropertyDescriptors()
    • value 当前对象的默认值
    • writable 是否可以修改
    • enumerable 是否可以通过 for..in 方式循环
    • configurable 是否可以删除

4. 字符串拓展

  • String.prototype.padStart() 头部补全
  • String.prototype.padEnd() 尾部补全第一个参数为长度,第二个参数为用于补全的字符串
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'

'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'

//等于或大于最大长度,则字符串补全不生效,返回原字符串
'xxx'.padStart(2, 'ab') // 'xxx'
'xxx'.padEnd(2, 'ab') // 'xxx'
//应用于日期  yyyy-mm-dd
const now = new Date()
const year = now.getFullYear()
//padStart 是 String 原型下面的方法,所以想要将其转换为 String
//getMonth()返回的是 0-11 的数字,所以要加 1
const month = (now.getMonth() + 1).toString().padStart(2,'0') 
const day = (now.getDate()) + 1.toString().padStart(2,'0')
console.log(`${year}-${month}-${day}`)
//加密手机号
const tel = '13011111111'
const NewTel = tel.slice(-4).padStart(tel.length,'*')
console.log(NewTel)

5. 尾逗号

允许数参数列表使用尾逗号。

ES9

1. 异步迭代 for await of

  • for-await-of
  • Symbol.asyncIterator
//同步迭代
const arr = ['es6','es7','es8','es9']
arr[Symbol.iterator] = function() {
    let nextIndex = 0
    return {
        next() {
            return nextIndex < arr.length ? {
                value: arr[nextIndex++],
                done: false
            } : {
                value: undefined,
                done: true
            }
        }
    }
}
for(let item of arr) {
    console.log(item)
}
//异步迭代
function getPromise(time) {
    return new Promise((resolve,reject) => {
        setTimeout(() => {
            resolve({  //写成对象的形式
                value: time,
                done:false
            })
        },time)
    })
}
const arr = [getPromise(1000),getPromise(2000),getPromise(3000)]
arr[Symbol.asyncIterator] = function() {
    let nextIndex = 0
    return {
        next() {
            return nextIndex < arr.length ? arr[nextIndex++] : 
            Promise.resolve({
                value: undefined,
                done: true
            })
        }
    }
}
async function test() {
    for await (let item of arr) {
        console.log(item)
    }
}
test()

2. 正则表达式拓展

  • dotAlldot 不能匹配n r(包括两者的 Unicode)
    const reg = /./s  //匹配任意单个字符
    console.log(reg.test('5'))  //true
    console.log(reg.test('x'))  //true
    console.log(reg.test('n'))  //true
    console.log(reg.test('r'))  //true
    console.log(reg.test('u{2028}'))  //true
    console.log(reg.test('u{2029}'))  //true
    
  • 具名组匹配
    const RE_DATE = /(d{4})-(d{2})-(d{2})/;  //用圆括号分组
    
    const matchObj = RE_DATE.exec('1999-12-31');
    const year = matchObj[1]; // 1999
    const month = matchObj[2]; // 12
    const day = matchObj[3]; // 31
    
    const reg = /(?d{4}-(?<month)d{2}-(?d{2}))
    const groups = reg.exec('2020-02-01').groups
    //使用解构赋值
    const {year, month,day} = groups
    console.log(year, month, day)
    
  • 后行断言 match
    • 先行断言:x只有在y前面才匹配,必须写成/x(?=y)/
    • 先行否定断言:x只有不在y前面才匹配,必须写成/x(?!y)/
    • 后行断言x只有在y后面才匹配,必须写成/(?<=y)x/
    • 后行否定断言:x只有不在y后面才匹配,必须写成/(?<!y)x/

3. 对象拓展 Rest&Spread

//克隆对象 为深拷贝
const obj3 = {..obj1}

//合并对象  为浅拷贝
const obj4 = {...obj1, ...obj2}  //obj1 和 obj2 相同键名的会被后者覆盖

//...rest 获取剩余的属性
const {name, age, ...rest} = obj1  //...rest 必须放在最后,不然会报错

4. Promise 拓展 finally()

  • Promise.prototype.finally()无论失败还是成功都会执行 finally 里面的语句【例如:成功失败相同的代码逻辑、关闭操作】

5. 字符串扩展

放松模板字符串文字限制,对一些错误不报错,返回 undefined。

ES10

1. 对象扩展

Object.fromEntries() 返回对象结构 【和Object.Entries()相反(返回键对结构)】

// map  =>  对象
const map = new Map()
map.set('name', 'n1')
map.set('name', 'n2')
console.log(map)
const fromEntries = Object.fromEntries(map)
console.log(map)  //对象格式

2. 字符串扩展

  • String.prototype.trimStart()【trimLeft()】 消除头部的空格,尾部会被保留
  • String.prototype.trimEnd() 【trimRight()】消除尾部的空格,头部会被保留
  • String.prototype.trim() 消除空格

3. 数组扩展

  • Array.prototype.flat(num) 对多维数组进行扁平化操作
    const arr = [1,2,3,[4,5,6,[7,8,9,10,11],12]]  //三维数组
    console.log(arr.flat().flat().flat())
    console.log(arr.flat(3))
    console.log(arr.flat(Infinity))
    
  • Array.prototype.flatMap()
    const arr = [1,2,3,4,5]
    //const res = arr.map(x => [x + 1]).flat() 等价于↓
    const res = arr.flatMap(x => [x + 1])
    

4. 修订 toString()

返回源代码中的实际文本片段【原样输出返回一模一样的原始代码,包括注释空格等等】。

5. 可选的 Catch Binding

省略 catch 绑定的参数和括号。

try {
  // ...
} catch {
  // ...
}

6. JSON 扩展

  • JSON superset
  • JSON.stringify() 增强能力
// JSON 超集 【少用】u2029 u2028
eval('var str = "youlan";u2029 function foo(){return str;}')
console.log(foo())
//0xD800~0xDfff
console.log(JSON.stringify('uD830uDE0E'))  //emoji
console.log(JSON.stringify('uD830'))  //ud830 原样输出

7. Symbol 扩展

Symbol.prototype.description 只读属性,不可写【修改 description 也不会报错,但是不能起作用】.

const s = Symbol('yl')
console.log(s)  //Symbol(yl)
console.log(s.description)  //yl 如果没有值则返回 undefined

ES11

1. 全局模式捕获 matchAll()

String.prototype.matchAll() 和正则一起使用

const str = `
    <html>
        <body>
            <div>第一个 div</div>
            <p>这是 p</p>
            <div>第二个 div</div>
            <span>这是 span</span>
            <div>第三个 div</div>
        </body>
    </html>
`
//exec g
function selectDiv1(regExp, str) {
    let matches = []
    while(true) {
        const match = regExp.exec(str)
        if(match == null) {
            break
        }
        matches.push(match[1]) //完整匹配
    }
    return matches
}
const regExp = /<div>(.*)</div>/g
const res1 = selectDiv1(regExp, str)
console.log(res1)  //["第一个 div","第二个 div","第三个 div"]

//match
//console.log(str.match(regExp))  //["<div>第一个 div</div>","<div>第二个 div</div>","<div>第三个 div</div>"]

//replace
function selectDiv2(regExp, str) {
	let matches = []
    str.replace(regExp, (all, first) => {
        matches.push(first) //完整匹配
    }) 
    return matches
}
const res2 = selectDiv2(regExp, str)
console.log(res2) //["第一个 div","第二个 div","第三个 div"]

//matchAll 
function selectDiv3(regExp, st){
    let matches = []
    for(let match of str.matchAll(regExp)){
        matches.push(match[1]) //完整匹配
    }
    return matches
}
const res3 = selectDiv3(regExp, str)
console.log(res3) //["第一个 div","第二个 div","第三个 div"]

matchAll方法的正则表达式需要有 g(全局匹配)

2. 动态导入 Dynamic import()

按需引入,使得页面渲染更快

懒加载

eg. 点击按钮才导入某个模块、才开始渲染这一部分的东西

3. 新的原始数据类型 BigInt

console.log(1n == 1) //true
console.log(1n === 1) //false

//创建
const bigInt = BigInt(900719925474740993n)
bigInt.toSring()

4. Promise 扩展 allSettled()

  • Promise.allSettled()
  • allSettled() Vs all()
Promise.allSettled([
    Promise.resolve({
        code: 200,
        data: [1, 2, 3]
    }),
    Promise.reject({
        code: 500,
        data: []
    }),
    Promise.resolve({
        code: 200,
        data: [7, 8, 9]
    }),
]).then(res => {
    //console.log(res,"成功")
    const data = res.filter(item => item.status === "fulfilled")
    console.log(data)
}).catch(err => {
    console.log(err,"失败")
})

如果使用all(),则其中有一个 reject 都会导致整个进程进入“失败”;而allSettled(),成功的会返回status: "fulfilled" value:{...},失败的返回reson: {...},使用 filter 进行过滤获得请求成功的数据

5. 全局对象 globalThis

提供一个标准的方式去获取不同环境下的全局对象

// node: global
// web: window self
const getGlobal = () => {
    if(typeof selt !== 'undefined'){
        return self
    }
    if(typeof window !== 'undefined'){
        return window
    }
    if(typeof global !== 'undefined'){
        return global
    }
    throw new Error("无法找到全局变量")
}
const global = getGlobal()
console.log(global)

//在 es11 中
//console.log(globalThis)

6. 可选链 Optional chaining

先判断这个方法属性是否存在,如果存在再往下取

const street = user && user.address && user.address.street
console.log(street)
const num = user && user.address && user.address.getNum && user.address.getNum()
console.log(num)

//es11 中,代码更加简洁
const street = user?.address?.street
console.log(street)
const num = user?.address?.getNum?.()
console.log(num)

?. 中间不能有空格

7. 空值合并运算符 Nullish coalescing Operator

const b = null
const a = b ?? 6  //当 b 为 undefined 或 null 时,取默认值
console.log(a)

?? 中间不能有空格

ES12

String.prototype.replaceAll()

在此之前只能使用正则替换,现在可以直接使用一个快捷方式;replaceAll

//前
'jxvxscript'.replace(/x/g, 'a');

//后
// jxvxscript becomes javascript
'jxvxscript'.replaceAll('x', 'a');

Promise.any

Promise.any() 接收一个Promise可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 。 如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise。

const promise1 = new Promise((resolve, reject) => reject('我是失败的 Promise_1'));
const promise2 = new Promise((resolve, reject) => reject('我是失败的 Promise_2'));
const promiseList = [promise1, promise2];
Promise.any(promiseList).then(values=>{  
  console.log(values);
})
.catch(e=>{  
  console.log(e);
});

WeakRefs

使用 WeakRefs 的 Class 类创建对对象的弱引用(对对象的弱引用是指当该对象应该被 GC 回收时不会阻止 GC 的回收行为)

Logical Assignment Operators

包括这些运算符:&&=||=??=

a = 1;
b = 2;
a&&=b // a=2

/*
以上代码相当于
a && a = b

??=
作用相当于
a ?? a = b
*/

Numeric Separators —— 数字分隔符

数字增加分隔符,可以使用 _ 分割数字,方便阅读较大的数字 对于跟数字打交道比较多的同学来说,可能会更加舒服

// previous syntax before ES12
const number = 92145723;

// new syntax coming with ES12
const number = 92_145_723;
console.log(number) // 92145723

//对国人来说可以这样,万,亿为单位
const number = 1_0000;
console.log(number) // 10000

结语

呼哈,终于整理完了,新鲜出炉的最全 ES6-ES12 新特性总结,希望对大家有用,整理不易,希望对大家有帮助。

标签:JavaScript

本文是由用户"游客"发布,所有内容的版权归原作者所有。没有经过书面许可,任何单位或个人不得以任何形式复制、转载、引用本网站的内容。否则将追究法律责任。

相关专题