该 ES6
内容包含了 ES7
、ES8
、ES9
、ES10
、ES11
的特性。我们通常会使用 ES6
来统一概括这些新特性。
{
let a = 888;
}
/**
* Uncaught ReferenceError: a is not defined
*/
console.log(a);
/**
* Uncaught ReferenceError: a is not defined
*/
console.log(a);
{
let a = 888;
}
{
let a = 888;
/**
* Uncaught SyntaxError: Identifier 'a' has already been declared
*/
let a = 666;
}
大部分特性相同,不同点:
const 设置的变量不可以再修改(对象类型除外)。
const a = 888;
/**
* Uncaught TypeError: Assignment to constant variable.
*/
a = 999;
const a = {};
/**
* 成功
*/
a.name = 'anny';
Promise
状态:Promise
实例方法: new Promise((resolve,reject)=>{
resolve(888)
})
.then(res=>{
console.log(res)
})
new Promise((resolve,reject)=>{
reject(888)
})
.catch(err=>{
console.log(err)
})
let num = 100;
new Promise((resolve,reject)=>{
if(num==100){
resolve(888)
}else{
reject(999)
}
})
.then(res=>{
console.log(res)
})
.catch(err=>{
console.log(err)
})
.finally(info=>{
console.log('finally!')
})
Promise
链式调用: new Promise((resolve,reject)=>{
resolve()
})
.then(res=>{
console.log(888)
})
.then(res=>{
console.log(999)
})
.then(res=>{
console.log(666)
})
Promise
同步执行异步函数:实现同步执行异步函数,只需要在每个回调中返回一个 Promise
对象即可。
function asyncMeth_one(){
return new Promise(resolve=>{
setTimeout(() => {
console.log('run 800!');
resolve()
}, 800);
})
}
function asyncMeth_two(){
return new Promise(resolve=>{
setTimeout(() => {
console.log('run 500!')
resolve()
}, 500);
})
}
new Promise((resolve,reject)=>{
resolve()
})
.then(res=>{
return asyncMeth_one();
})
.then(res=>{
return asyncMeth_two();
})
当使用 new
关键词调用 类
时,会自动调用 constructor
。
class People{
constructor(){
console.log('被 new 了');
}
}
new People();
当继承时,如果子类使用了 constructor
构造器,则必须使用 super
关键词。
class Earth {
constructor(name){
this.name = name;
}
}
class People extends Earth{
constructor(){
super('anny');
console.log(this.name);
}
}
new People();
箭头函数的 this
指向作用域链的上一层。
function test(){
this.name = 'anny';
let arrow = ()=>{
console.log(this.name);
}
arrow();
}
test();
new
命令因为箭头函数没有自己的 this
,所以不可以用做 构造函数
。
arguments
对象Generator
函数函数参数可以设置默认值:
function test(a,b=100){
return a+b;
}
console.log(test(80));
注意:函数默认值不会更改函数 arguments
的值。
通常,我们需要非常复杂的连接字符串。
function test(){
let name = 'anny';
let age = 22;
return "My name is " + name + "; age is "+ age;
}
console.log(test());
但是我们可以通过使用模板字符串来大大简化这一点。
function test(){
let name = 'anny';
let age = 22;
return `My name is ${name}; age is ${age}`;
}
console.log(test());
let obj = {
name:'anny',
age:22
}
let {age} = obj;
console.log(age);
let obj = {
name:'anny',
age:22
}
let {age:Myage} = obj;
console.log(Myage);
let key = 'age';
let obj = {
name:'anny',
age:22
}
let {[key]:Myage} = obj;
console.log(Myage);
我们这里拿 console
为例:
let {log} = console;
log(888);
let [a] = [1,2,3,4,5,6];
console.log(a);
只使用部分位置下标值,可以使用 逗号
分割。
let [,,,a] = [1,2,3,4,5,6];
console.log(a);
这里输出 4
。
let a = [1,2,3,4,5,6];
console.log(...a);
function test(a, b, c) {
console.log(`a:${a},b:${b},c:${c}.`)
}
let arr = [1,2,3];
test(...arr); //a:1,b:2,c:3.
function test(...a) {
console.log(a)
}
let arr = [1, 2, 3];
test(...arr); //[1,2,3]
let arr1 = [4, 5, 6];
let arr2 = [1, 2, 3, ...arr1];
console.log(arr2); //[1,2,3,4,5,6]
对象属性名
和 变量/函数
名称相同时就可以进行缩写。
比如:
let age = 20;
let obj = {
age: age
}
/**
* 缩写
*/
let obj1 = {
age
}
let obj = {
speak: function speak() {
console.log('speak')
}
}
/**
* 缩写
*/
let obj1 = {
speak() {
console.log('speak')
}
}
注意:script
标签使用模块化需要设置 type="module"
属性。另外,本地运行,会有跨域提醒。需要搭建一个服务器解决。
import {name} from './test.js'
import {name as names} from './test.js'
import * as names from './test.js'
console.log(names.name)
export const name = 'anny';
export const age = 22;
export default {
name:'anny',
age:20
}
import name from './test.js'
includes用于判断数组中是否包含指定的值。
返回值:true/false
let arr = [1,2,3];
console.log(arr.includes(2))
可以指定查找 起始位置
。
let arr = [1,2,3];
console.log(arr.includes(2,1))
console.log(2**3) //8
等同于:2*2*2
用于同步执行异步函数:
async function test() {
await setTimeout(() => {
console.log(8888)
}, 2000);
console.log(999)
}
test(); //999 8888
其实 await
渴望接收一个 Promise
期约:
function asyncMeth(){
return new Promise(resolve=>{
setTimeout(()=>{
console.log(8888)
resolve();
},1000)
})
}
async function test() {
await asyncMeth();
console.log(999)
}
test(); // 8888 999
async function test() {
await console.log(888);
console.log(999)
}
test();
console.log(666)
输出:888 666 999
返回一个包含对象所有 属性值
的数组。
和 for in
的区别,for in
会遍历原型链。
let obj = {
name:'anny',
age:20
}
console.log(Object.values(obj));
输出:['anny', 20]
返回一个包含对象所有 属性名
的数组。
let obj = {
name:'anny',
age:20
}
console.log(Object.keys(obj));
输出:['name', 'age']
返回一个包含对象自身可枚举属性的键值对数组。
let obj = {
name:'anny',
age:20
}
console.log(Object.entries(obj));
输出:[['name', 'anny'] , ['age', 20]]
Object.getOwnPropertyDescriptors() 方法用来获取一个对象的所有自身属性的描述符
。
对象属性描述符:
描述符
是否可以被改变/删除(默认false)value
是否可以被改变(默认false)padStart()/padEnd()
都属于填充字符串,只是填充开始位置不同。
let str = '7878'
console.log(str.padStart(10,"*"))
输出:******7878
let str = '7878'
console.log(str.padEnd(10,"*"))
输出:7878******
JavaScript 是单线程的,如果要使用多线程,可以使用 Workers
对象:
主线程用于与用户交互,Worker
线程用于承担计算任务
var myWorker = new Worker('test.js');
SharedArrayBuffer
的大部分作用是创建一块公共内存,供 主线程
和 Workers
线程共同读写。
Atomics
作用是提供一组静态方法对 SharedArrayBuffer
和 ArrayBuffer
对象进行原子操作。
什么是原子操作?
原子操作:多个共享内存的线程能够同时读写同一位置上的数据。原子操作会确保正在读或写的数据的值是符合预期的,即下一个原子操作一定会在上一个原子操作结束后才会开始,其操作过程不会中断。
let arr = [
1,
2,
3
]
如果想要在数组中再添加一条数据(第 5
行),需要先在第 4
行添加一个 逗号
,然后再添加数据。但在 版本比较
中会提醒第 4
行发生了改变。
为了方便 比较(diff)
,提案了 尾后逗号
。
它看起来就像这样:
let arr = [
1,
2,
3,
]
for await 可异步迭代 实现异步迭代器协议的对象
。
function * asyncMeth(){
yield import('./test.js')
yield import('./test3.js')
}
for await (let aa of asyncMeth()) {
console.log(aa);
}
function test(msg) {
console.log(msg)
}
test`this is anny`
就像看到的关于22.2:《带标签的模版字面量及转义序列》
,解析器转义都是根据那些规则去查找有效的转义序列。
但提议者认为带标签的模版字符串应该 允许嵌套支持常见转义序列
的语言。
如:
function test(msg) {
console.log(msg)
}
test`\unicode`
如果根据 22.2:《带标签的模版字面量及转义序列》
规则,该功能不能运行。
总的概括来说,就是允许更广泛的自定义写法,可以使用 undefined
代替解析不了的值,使用 raw
返回原始传入的字符串,而不是无法运行的 报错
。
这里只列出了一部分,更多详情请到搜索引擎查询。
首先看一下 组匹配
:
let rep= /(\w{5})-(\w{8})/;
console.log(rep.exec("China-ShanDong"))
输出:
0: "China-ShanDong"
1: "China"
2: "ShanDong"
groups: undefined
index: 0
input: "China-ShanDong"
length: 3
加个名称构成 具名组匹配
(名称尽量使用英文,这里仅便于观察):
let rep= /(?<国家>\w{5})-(?<城市>\w{8})/;
console.log(rep.exec("China-ShanDong"))
输出:
0: "China-ShanDong"
1: "China"
2: "ShanDong"
groups:{
国家: "China"
城市: "ShanDong"
}
index: 0
input: "China-ShanDong"
length: 3
可以使用 \k<组名>$
的写法引用某个 具名组匹配
。
let rep= /(?<名字>\w{4})-\k<名字>$/;
console.log(rep.test("anny-anny")) // true
console.log(rep.test("anny-anny1")) // false
对于 无法编码
的字符串,返回 转义字符串
。
简单来说就是遇到无法编码的字符串时,直接返回你传入的原始字符串(之前是报错)。
按照指定的深度递归数组,将所有元素和遍历到的子数组数据合并为一个新数组返回。
let arr = [1,2,3,[4,5,6]]
console.log(arr.flat(1))
输出:[1, 2, 3, 4, 5, 6]
let arr = [1,2,3,[[4,5,6]]]
console.log(arr.flat(1))
输出:[1, 2, 3, [4, 5, 6]]
flatMap
使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 flat(1)
返回的值几乎相同。
let arr = [1,2,3,[4,5,6]]
console.log(arr.flatMap(e=>e))
输出:[1, 2, 3, 4, 5, 6]
顾名思义,一个是删除开始位置的空格,另一个是删除末尾位置的空格。
let str =` 123 `;
console.log(str.trimStart())
console.log(str.trimEnd())
Object.fromEntries()
作用是把键值对列表转换为一个对象。
如:
let arr = [
['name','anny'],
['age',20]
]
console.log(Object.fromEntries(arr));
输出:
{
age: 20
name: "anny"
}
Symbol.prototype.description
:返回 Symbol
对象的可选描述的字符串。
与 Symbol.prototype.toString()
的区别:
let a = Symbol('hello')
console.log(a.toString())
console.log(a.description);
a.toString()
输出:Symbol(hello)
a.description
输出:hello