1、es6

1.1 class类

1.1.1 类的基本使用

class Person {// 注意: 一个类只能有一个构造函数// 当我们通过 new 关键字操作类的时候,会调用这个 constructor 函数,并且执行如下操作// 1.在内存中创建一个对象 moni = {}// 2.将类的原型prototype赋值给创建出来的对象 moni.__proto__ = Person.prototype// 3.将对象赋值给函数的this: new绑定 this = moni// 4.执行函数体中的代码// 5.自动返回创建出来的对象constructor(name, age) {this.name = name;this.age = age;}
}
var p1 = new Person("呆呆狗", 20);
console.log(p1);

1.1.2 类的方法

var names = ["abc", "cba", "nba"];
class Person {constructor(name, age) {this.name = name;this.age = age;this._address = "山东";}// 其实这个方法,会被放到 Person的原型身上eating() {console.log(this.name + " eating·~");}// 类的访问器方法get address() {console.log("拦截访问操作");return this._address;}set address(newAddress) {console.log("拦截设置操作");this._address = newAddress;}// 类的静态方法,也称为 类方法,  直接通过类名. d// Person.randomPerson 可以直接这样访问static randomPerson() {var nameIndex = Math.floor(Math.random() * names.length);var name = names[nameIndex];var age = Math.floor(Math.random() * 100);return new Person(name, age);}
}
var p1 = new Person("呆呆狗", 20);
console.log(p1);
p1.eating();
p1.address = "青岛";
console.log("p1修改address后的", p1);
// console.log(p1.randomPerson()); //这样调用是错误的
console.log(Person.randomPerson());

1.2 字面量的增强

var name = "ddg"
var age = 18
var obj = {// 属性的简写name,age,// 方法的简写foo() {},[name + '134']: "哈哈哈哈嗝"
}
console.log(obj);

1.3 解构

数组的解构

var names = ["abc", "cba", "nba"]
// var item1 = names[0]
// var item2 = names[1]
// var item3 = names[2]// 对数组的解构: []
var [item1, item2, item3] = names
console.log(item1, item2, item3)// 解构后面的元素
var [, , itemz] = names
console.log(itemz)// 解构出一个元素,后面的元素放到一个新数组中
var [itemx, ...newNames] = names
console.log(itemx, newNames)// 解构的默认值
var [itema, itemb, itemc, itemd = "aaa"] = names
console.log(itemd)

对象的解构

var obj = {name: "why",age: 18,height: 1.88
}// 对象的解构: {}
var { name, age, height } = obj
console.log(name, age, height)var { age } = obj
console.log(age)var { name: newName } = obj
console.log(newName)var { address: newAddress = "广州市" } = obj
console.log(newAddress) //  广州市function foo(info) {console.log(info.name, info.age)
}foo(obj)function bar({ name, age }) {console.log(name, age)
}bar(obj)

1.4 let const

  • const本质上传递的值 是不可以修改的,(引用类型除外)
  • let 、const 不可以重复定义相同名字的变量
  • let/const他们是没有作用域提升
// var foo = "foo"
// let bar = "bar"// const constant(常量/衡量)
// const name = "abc"
// name = "cba"// 注意事项一: const本质上是传递的值不可以修改
// 但是如果传递的是一个引用类型(内存地址), 可以通过引用找到对应的对象, 去修改对象内部的属性, 这个是可以的
// const obj = {//   foo: "foo"
// }// // obj = {}
// obj.foo = "aaa"
// console.log(obj.foo)// 注意事项二: 通过let/const定义的变量名是不可以重复定义
// var foo = "abc"
// var foo = "cba"let foo = "abc"
// SyntaxError: Identifier 'foo' has already been declared
let foo = "cba"console.log(foo)

1.5 es5的作用域

// 声明对象的字面量
// var obj = {//   name: "why"
// }// ES5中没有块级作用域
// 块代码(block code)
// {//   // 声明一个变量 ,在es5 的时候,这个大括号,没有意义
//   var foo = "foo"
// }// console.log(foo)// 在ES5中只有两个东西会形成作用域
// 1.全局作用域
// 2.函数作用域
// function foo() {//   var bar = "bar"
// }// console.log(bar) // 访问不到function foo() {function demo() {}
}

1.6 es6的作用域

// ES6的代码块级作用域
// 对let/const/function/class声明的类型是有效
{let foo = "why"function demo() {console.log("demo function")}class Person { }
}// console.log(foo) // foo is not defined
// 不同的浏览器有不同实现的(大部分浏览器为了兼容以前的代码, 让function是没有块级作用域)
// demo() // 可以调用
var p = new Person() // Person is not defined
{}// if语句的代码就是块级作用域
// if (true) {//   var foo = "foo"
//   let bar = "bar"
// }// console.log(foo) // 可以访问
// console.log(bar) // 不可以访问// switch语句的代码也是块级作用域
// var color = "red"// switch (color) {//   case "red":
//     var foo = "foo"
//     let bar = "bar"
// }// console.log(foo) // 可以访问
// console.log(bar) // 不可以访问// for语句的代码也是块级作用域
// for (var i = 0; i < 10; i++) {//   // console.log("Hello World" + i)
// }// console.log(i) //可以访问for (let i = 0; i < 10; i++) {}console.log(i) // 不可以访问

1.7 块级作用域的应用场景

const btns = document.getElementsByTagName('button')// for (var i = 0; i < btns.length; i++) {//   (function(n) {//     btns[i].onclick = function() {//       console.log("第" + n + "个按钮被点击")
//     }
//   })(i)
// }// console.log(i)for (var i = 0; i < btns.length; i++) {btns[i].onclick = function () {console.log("第" + i + "个按钮被点击")// 点击的时候  输出的 永远是  第4个按钮被点击}
}console.log(i)

1.8 模板字符串

// ES6之前拼接字符串和其他标识符
const name = "why"
const age = 18
const height = 1.88// console.log("my name is " + name + ", age is " + age + ", height is " + height)// ES6提供模板字符串 ``
const message = `my name is ${name}, age is ${age}, height is ${height}`
console.log(message)const info = `age double is ${age * 2}`
console.log(info)function doubleAge() {return age * 2
}const info2 = `double age is ${doubleAge()}`
console.log(info2)

1.9 模板字符串调用函数

// 第一个参数依然是模块字符串中整个字符串, 只是被切成多块,放到了一个数组中
// 第二个参数是模块字符串中, 第一个 ${}
function foo(m, n, x) {console.log(m, n, x, "---------");// 如果是 模板字符串调用的方式// 输出结果是:   ['Hello', 'Wo', 'rld', raw: Array(3)] 'why' 18 '---------'
}// foo("Hello", "World")// 另外调用函数的方式: 标签模块字符串
// foo``// foo`Hello World`
const name = "why";
const age = 18;
// ['Hello', 'Wo', 'rld']
foo`Hello${name}Wo${age}rld`;

1.10 函数的默认参数

// ES5以及之前给参数默认值
/*** 缺点:*  1.写起来很麻烦, 并且代码的阅读性是比较差*  2.这种写法是有bug*/
// function foo(m, n) {//   m = m || "aaa"
//   n = n || "bbb"//   console.log(m, n)
// }// 1.ES6可以给函数参数提供默认值
function foo(m = "aaa", n = "bbb") {console.log(m, n)
}// foo()
foo(0, "")// 2.对象参数和默认值以及解构
// 给它一个 有 name 和 age 的对象
function printInfo({ name, age } = { name: "why", age: 18 }) {console.log(name, age)
}printInfo({ name: "kobe", age: 40 })// 另外一种写法
// 给它一个空对象,然后 添加默认值
function printInfo1({ name = "why", age = 18 } = {}) {console.log(name, age)
}printInfo1()// 3.有默认值的形参最好放到最后
function bar(x, y, z = 30) {console.log(x, y, z)
}// bar(10, 20)
bar(undefined, 10, 20)// 4.有默认值的函数的length属性
function baz(x, y, z, m, n = 30) {console.log(x, y, z, m, n)
}console.log(baz.length) // 有默认值的参数开始往后都不算在length里面 ,有默认值的参数,不算在 length

1.11 函数的剩余参数

// 函数的剩余参数
function foo(first, ...arr) {console.log(first, arr); //1 , [2, 3, 4, 5, 6]
}
foo(1, 2, 3, 4, 5, 6);

1.12 箭头函数

  1. 相比以前,有更简单的写法
  2. 箭头函数不绑定this,会捕获其所在上下文的this,作为自己的this
  3. 箭头函数是匿名函数,不能作为构造函数,不可以使用new命令,否则后抛出错误
  4. 箭头函数不绑定arguments
  5. 使用call,apply,bind并不会改变箭头函数中的this指向
  6. 箭头函数没有原型对象prototype这个属性

1.13 展开运算符

  • 展开语法(Spread syntax)

    • 可以在函数调用/数组构造时,将数组表达式或者string在语法层面展开
    • 还可以在构造字面量对象时,将对象表达式按key-value的方式展开
  • 展开语法的场景
    • 在函数调用时
    • 在数组构造时
    • 在构造对象字面量时,也可以使用展开运算符,(ES9,es2018增加的)
const names = ["abc", "cba", "nba"]
const name = "why"
const info = {name: "why", age: 18}// 1.函数调用时
function foo(x, y, z) {console.log(x, y, z)
}// foo.apply(null, names)
foo(...names)
foo(...name)// 2.构造数组时
const newNames = [...names, ...name]
console.log(newNames)// 3.构建对象字面量时ES2018(ES9)
const obj = { ...info, address: "广州市", ...names }
console.log(obj)

1.14 Symbol

// 2.ES6中Symbol的基本使用
const s1 = Symbol()
const s2 = Symbol()console.log(s1 === s2)// ES2019(ES10)中, Symbol还有一个描述(description)
const s3 = Symbol("s3的描述")
console.log(s3.description)// 's3的描述'// 3.Symbol值作为key
// 3.1.在定义对象字面量时使用
const obj = {[s1]: "abc",[s2]: "cba"
}// 3.2.新增属性
obj[s3] = "nba"
console.log('obj', obj);
// 3.3.Object.defineProperty方式
const s4 = Symbol()
Object.defineProperty(obj, s4, {enumerable: true, // 是否可枚举configurable: true, // 是否可删除writable: true, // 是否可重写value: "mba"
})console.log(obj[s1], obj[s2], obj[s3], obj[s4])
// 注意: 不能通过.语法获取
// console.log(obj.s1)// 4.使用Symbol作为key的属性名,在遍历/Object.keys等中是获取不到这些Symbol值
// 需要Object.getOwnPropertySymbols来获取所有Symbol的key
console.log(Object.keys(obj))
console.log(Object.getOwnPropertyNames(obj))
console.log(Object.getOwnPropertySymbols(obj))
const sKeys = Object.getOwnPropertySymbols(obj)
for (const sKey of sKeys) {console.log(obj[sKey])
}// 5.Symbol.for(key)/Symbol.keyFor(symbol)
const sa = Symbol.for("aaa")
const sb = Symbol.for("aaa")
console.log(sa === sb) // 在key 相同的情况下,他俩是一样的const key = Symbol.keyFor(sa)
console.log(key) // 返回 sa 的 key
const sc = Symbol.for(key)
console.log(sa === sc)console.log('~~~~~~~~~~~~~');
const ddg1 = Symbol('呆呆狗')
const ddg2 = Symbol('呆呆狗')
console.log(ddg1 === ddg2); // 不相等

1.15 Set

// 10, 20, 40, 333
// 1.创建Set结构
const set = new Set()
set.add(10)
set.add(20)
set.add(40)
set.add(333)set.add(10)// 2.添加对象时特别注意: 会创建出来两个对象,他们两个指向的是不同的地址
set.add({})
set.add({})const obj = {}
set.add(obj) // 这个时候存放的就是同一个对象,添加的地址都是同一个
set.add(obj)// console.log(set)// 3.对数组去重(去除重复的元素)
const arr = [33, 10, 26, 30, 33, 26]
// const newArr = []
// for (const item of arr) {//   if (newArr.indexOf(item) !== -1) {//     newArr.push(item)
//   }
// }const arrSet = new Set(arr)
// const newArr = Array.from(arrSet)
// const newArr = [...arrSet]
// console.log(newArr)// 4.size属性
console.log(arrSet.size)// 5.Set的方法
// add
arrSet.add(100)
console.log(arrSet)// delete
arrSet.delete(33)
console.log(arrSet)// has
console.log(arrSet.has(100))// clear
// arrSet.clear()
console.log(arrSet)// 6.对Set进行遍历 1.forEach  or  for of
arrSet.forEach(item => {console.log(item)
})for (const item of arrSet) {console.log(item)
}

1.16 WeakSet

和Set 类似,也是内部元素不能重复的数据结构

其实它的应用场景很少

  • WeakSet 中只能存放 对象类型 ,不能存放基本数据类型
  • WeakSet 对元素的引用是弱引用,如果没有其他引用对某个对象进行引用,那么GC可以对该对象进行回收

常见方法

  • WeakSet 常见的方法

    • add(value):添加某个元素,返回WeakSet对象本身
    • delete(value):从WeakSet中删除和这个值相等的元素,返回Boolean类型
    • has(value):判断WeakSet中是否存在某个元素,返回布尔类型
  • 注意:WeakSet 不能遍历
    • 因为WeakSet 只是对对象的弱引用,如果我们遍历获取到其中的元素,那么有可能造成对象不能正常的销毁
    • 所以存储到WeakSet 的对象,是没办法获取的


假设,是Set 结构,把 obj = null 以后, 0x100也不会销毁,因为Set里面 还有一个元素在引用着 0x100

如果是 WeakSet 结构,obj=null 以后,0x100 会被回收的。因为如果没有其他引用对 0x100 进行引用,所以0x100 会被回收

1.17 Map

map数据结构,用于存储映射关系
之前,对象只能用字符串/Symbol来作为 key,

// 1.JavaScript中对象中是不能使用对象来作为key的
const obj1 = { name: "why" }
const obj2 = { name: "kobe" }// const info = {//   [obj1]: "aaa",
//   [obj2]: "bbb"
// }// 当我们把 obj1 作为对象key 的时候,它会转成字符串格式 作为key, obj2也是如此,并且转换完的结果是一样的
// console.log(info) // { '[object Object] : ' : 'bbb' }// 2.Map就是允许我们对象类型来作为key的
// 构造方法的使用
const map = new Map()
map.set(obj1, "aaa")
map.set(obj2, "bbb")
map.set(1, "ccc")
console.log('map', map) // {{…} => 'aaa', {…} => 'bbb', 1 => 'ccc'}// 如果要传递一个数组,则必须按照 [ [key,value],[key,value] ] ,数组套数组,第二层数组里面是 key,value
const map2 = new Map([[obj1, "aaa"], [obj2, "bbb"], [2, "ddd"]])
console.log('map2', map2)// 3.常见的属性和方法
console.log(map2.size)// set
map2.set("why", "eee")
console.log(map2)// get(key)
console.log(map2.get("why"))// has(key)
console.log(map2.has("why"))// delete(key)
map2.delete("why")
console.log(map2)// clear
// map2.clear()
// console.log(map2)// 4.遍历map
map2.forEach((item, key) => {console.log(item, key)
})for (const item of map2) {console.log(item[0], item[1])
}for (const [key, value] of map2) {console.log(key, value)
}

1.18 WeakMap

在vue3的响应式原理,就用到了

  • 区别一:WeakMap的key只能使用对象,不接受其他的类型作为key;

  • 区别二:WeakMap的key对对象想的引用是弱引用,如果没有其他引用引用这个对象,那么GC可以回收该对象;

WeakMap常见方法

  • set(key, value):在Map中添加key、value,并且返回整个Map对象;

  • get(key):根据key获取Map中的value;

  • has(key):判断是否包括某一个key,返回Boolean类型;

  • delete(key):根据key删除一个键值对,返回Boolean类型;


假设,是Map 结构,把 obj = null 以后, 0x100也不会销毁,因为map里面 还有一个key 在引用着 0x100

如果是 WeakMap 结构,obj=null 以后,0x100 会被回收的。因为如果没有其他引用对 0x100 进行引用,所以0x100 会被回收

1.19 promise

1.19.1 Promise.resolve

/*** resolve(参数)*  1> 普通的值或者对象  pending -> fulfilled*  2> 传入一个Promise*    那么当前的Promise的状态会由传入的Promise来决定*    相当于状态进行了移交*  3> 传入一个对象, 并且这个对象有实现then方法(并且这个对象是实现了thenable接口)*    那么也会执行该then方法, 并且又该then方法决定后续状态*/// 1.传入Promise的特殊情况
// const newPromise = new Promise((resolve, reject) => {//   // resolve("aaaaaa")
//   reject("err message")
// })// new Promise((resolve, reject) => {//   // pending -> fulfilled
//   resolve(newPromise)
// }).then(res => {//   console.log("res:", res)
// }, err => {//   console.log("err:", err)
// })// 2.传入一个对象, 这个兑现有then方法
new Promise((resolve, reject) => {// pending -> fulfilledconst obj = {then: function (resolve, reject) {// resolve("resolve message")reject("reject message")}}resolve(obj)
}).then(res => {console.log("res:", res) // 这里的res 或者err 并不是 obj 这个对象,而是obj.then 这个方法里面的 传递过来的值,因为这个obj 对象 有 then 方法,所以会默认执行这个方法
}, err => {console.log("err:", err)
})// eatable/runable
const obj = {eat: function () {},run: function () {}
}

1.19.2 Promise.then

  • 同一个promise,可以被多次调用 then 方法
  • then 方法传入的回调函数,也是拥有返回值的
    • 如果我们返回的是一个普通值(数值/字符串/普通对象/undefined), 那么这个普通的值被作为一个新的Promise的resolve值(就是说可以链式调用)
    • 如果我们返回的是一个Promise,继续链式调用
    • 如果返回的是一个对象, 并且该对象实现了thenable,相当于返回了一个新的promise
// Promise有哪些对象方法
// console.log(Object.getOwnPropertyDescriptors(Promise.prototype)) // catch、constructor、finally、then、Symbolconst promise = new Promise((resolve, reject) => {resolve("hahaha")
})// 1.同一个Promise可以被多次调用then方法
// 当我们的resolve方法被回调时, 所有的then方法传入的回调函数都会被调用
// 就是说控制台会输出 res1、res2、res3
// promise.then(res => {//   console.log("res1:", res)
// })// promise.then(res => {//   console.log("res2:", res)
// })// promise.then(res => {//   console.log("res3:", res)
// })// 2.then方法传入的 "回调函数: 可以有返回值
// then方法本身也是有返回值的, 它的返回值是Promise// 1> 如果我们返回的是一个普通值(数值/字符串/普通对象/undefined), 那么这个普通的值被作为一个新的Promise的resolve值
// promise.then(res => {//   console.log('then第1层');
//   return "aaaaaa"
// }).then(res => {//   console.log('then第2层', "res:", res) // 此时的 res 是前面的 return 的值的promise
//   return "bbbbbb"
// })// 2> 如果我们返回的是一个Promise
// promise.then(res => {//   return new Promise((resolve, reject) => {//     setTimeout(() => {//       resolve(111111)
//     }, 3000)
//   })
// }).then(res => {//   console.log("res:", res)
// })// 3> 如果返回的是一个对象, 并且该对象实现了thenable
// 返回一个对象,仍然会生成一个新的promise
promise.then(res => {return {then: function (resolve, reject) {resolve(222222)}}
}).then(res => {console.log("res:", res)
})

1.19.3 Promise.catch

事实上catch方法也是会返回一个Promise对象的,所以catch方法后面我们可以继续调用then方法或者catch方法

// catch 也可以多次调用
const promise = new Promise((resolve, reject) => {reject("111111")
})
promise.then(() => { }, (err) => {// 如果  new Promise 参数的回调,执行 reject() ,那么 这里就会捕捉到,而不会执行.catchconsole.log('then里面失败的回调');throw new Error('222')
}).catch(err => {console.log('catch失败的回调');
})promise.catch(() => {console.log('第二个catch');
})

1.19.4 Promise.finally

finally是在ES9(ES2018)中新增的一个特性:表示无论Promise对象无论变成fulfilled还是reject状态,最终都会被执行的代码。

finally方法是不接收参数的,因为无论前面是fulfilled状态,还是reject状态,它都会执行。

const promise = new Promise((resolve, reject) => {// resolve("resolve message")reject("reject message")
})promise.then(res => {console.log("res:", res)
}).catch(err => {console.log("err:", err)
}).finally(() => {console.log("finally code execute")
})

1.19.5 Promise.resolve

Promise.resolve的用法相当于new Promise,并且执行resolve操作,它的返回值是一个promise

resolve参数的形态

  • 情况一:参数是一个普通的值或者对象
  • 情况二:参数本身是promise
  • 情况三:参数是一个thenable
const promise = Promise.resolve({ name: "why" })
// 相当于
const promise2 = new Promise((resolve, reject) => {resolve({ name: "why" })
})// 2.传入Promise
const promise = Promise.resolve(new Promise((resolve, reject) => {resolve("11111")// reject('错误')  // 如果执行 reject() 那边会走到 catch
}))promise.then(res => {console.log("res:", res)
}).catch(err => {console.log(err);
})

1.19.6 Promise.reject

reject方法类似于resolve方法,只是会将Promise对象的状态设置为reject状态

Promise.reject的用法相当于new Promise,只是会调用reject

const promise1 = Promise.reject(new Promise(() => { }))promise1.then(res => {console.log("res1:", res)
}).catch(err => {console.log("err1:", err)// 这个时候,以 new Primise 的状态为准,但是这个promise 现在的状态是 pending
})
const promise2 = Promise.reject(new Promise((resolve, reject) => {resolve('promise2 成功')
}))promise2.then(res => {console.log("res2:", res)
}).catch(err => {// 因为 Promise.reject // 还是会走这个 错误的回调,console.log("err2:", err)return err
}).then(res => {// 如果 .catch 里面没有 return err ,那么在then 里面则会输出 undefined// 这里会输出 promise2 成功console.log('Promise.reject里面的成功回调的监听:  ', res);
})

1.19.7 Promise.all

// 创建多个Promise
const p1 = new Promise((resolve, reject) => {setTimeout(() => {resolve(11111)}, 1000);
})const p2 = new Promise((resolve, reject) => {setTimeout(() => {reject(22222)// resolve(222)}, 2000);
})const p3 = new Promise((resolve, reject) => {setTimeout(() => {resolve(33333)}, 3000);
})// 需求: 所有的Promise都变成fulfilled时, 再拿到结果
// 意外: 在拿到所有结果之前, 有一个promise变成了rejected, 那么整个promise是rejected
/*** Promise.all 返回值是一个数组。和 参数 顺序相同的一个数组* 它的参数如果不是 promise,也会转成promise* 它是等所有的promise都成功,以后在执行* 如果有一个promise 调用了 reject 那么 会直接走 catch *  */Promise.all([p2, p1, p3, "aaaa"]).then(res => {console.log(res)
}).catch(err => {console.log("err:", err)
})

1.19.8 Promise.allSettled

  • all方法有一个缺陷:当有其中一个Promise变成reject状态时,新Promise就会立即变成对应的reject状态

    • 那么对于resolved的,以及依然处于pending状态的Promise,我们是获取不到对应的结果的
  • 在ES11(ES2020)中,添加了新的API Promise.allSettled
    • 该方法会在所有的Promise都有结果(settled),无论是fulfilled,还是reject时,才会有最终的状态
    • 并且这个Promise的结果一定是fulfilled的
// 创建多个Promise
const p1 = new Promise((resolve, reject) => {setTimeout(() => {resolve(11111)}, 1000);
})const p2 = new Promise((resolve, reject) => {setTimeout(() => {reject(22222)}, 2000);
})const p3 = new Promise((resolve, reject) => {setTimeout(() => {resolve(33333)}, 3000);
})// allSettled
/** * 它的返回值是一个数组,数组里面是一个对象* [{"status": "fulfilled","value": 11111},{"status": "rejected","reason": 22222},{"status": "fulfilled","value": 33333}
]
*/
Promise.allSettled([p1, p2, p3]).then(res => {console.log(res)
}).catch(err => {console.log(err)
})

1.19.9 Promise.race

race是竞技、竞赛的意思,表示多个Promise相互竞争,谁先有结果,那么就使用谁的结果

// 创建多个Promise
const p1 = new Promise((resolve, reject) => {setTimeout(() => {resolve(11111)}, 3000);
})const p2 = new Promise((resolve, reject) => {setTimeout(() => {reject(22222)}, 500);
})const p3 = new Promise((resolve, reject) => {setTimeout(() => {resolve(33333)}, 1000);
})// race: 竞技/竞赛
// 只要有一个Promise变成fulfilled(完成状态)状态, 那么就结束
// 意外:
Promise.race([p1, p2, p3]).then(res => {console.log("res:", res)
}).catch(err => {console.log("err:", err)
})

1.19.10 Promise.any

any方法是ES12中新增的方法,和race方法是类似的

  • any方法会等到一个fulfilled状态,才会决定新Promise的状态
  • 如果所有的Promise都是reject的,那么也会等到所有的Promise都变成rejected状态
  • 如果所有的Promise都是reject的,那么会报一个AggregateError的错误

2、es7

2.1 includes

const names = ["abc", "cba", "nba", "mba", NaN]if (names.indexOf("cba") !== -1) {console.log("包含abc元素")
}// ES7 ES2016
// 第二个参数,从 索引值2 开始
if (names.includes("cba", 2)) {console.log('从2查找包含 cba');
}if (names.indexOf(NaN) !== -1) {// 不可以判断是否有 NaNconsole.log("包含NaN")
}if (names.includes(NaN)) {// 可以正确判断 是否有 NaNconsole.log("包含NaN,includes")
}

2.2 指数运算

const result1 = Math.pow(3, 3)
// ES7: **
const result2 = 3 ** 3
console.log(result1, result2)

3、es8

3.1 Object.keys

const obj = {name: "呆呆狗",age: 20
}console.log(Object.keys(obj)); // [ 'name', 'age' ]
console.log(Object.values(obj));// [ '呆呆狗', 20 ]
// Object.values如果传入数组,那么返回的就是数组本身
// Object.values如果传入字符串,那么返回值,是把 字符串分割成数组

3.2 Object.entries

const obj = {name: "呆呆狗",age: 20
}console.log(Object.entries(obj)); // [ [ 'name', '呆呆狗' ], [ 'age', 20 ] ]
const objEntries = Object.entries(obj)
objEntries.forEach(item => {console.log(item[0], item[1]);
})console.log(Object.entries(['a', 'b', 'c'])); // [ [ '0', 'a' ], [ '1', 'b' ], [ '2', 'c' ] ]
console.log(Object.entries('abc')); // [ [ '0', 'a' ], [ '1', 'b' ], [ '2', 'c' ] ]

3.3 padStart padEnd

const message = "Hello World"
// 第一个参数,是字符串填充完的长度,第二个参数默认是空格
const newMessage = message.padStart(15, "*").padEnd(20, "-")
console.log(newMessage) // ****Hello World-----// 案例
const cardNumber = "321324234242342342341312"
const lastFourCard = cardNumber.slice(-4)//截取最后四位
const finalCard = lastFourCard.padStart(cardNumber.length, "*")
console.log(finalCard) // ********************1312

3.4 Trailing-Commas

function foo(m, n,) {}foo(20, 30,) // 最后多加一个逗号 是没事的

3.5 async await

先空着

3.6 Object.getOwnPropertyDescriptors

这个方法主要的作用是返回属性的描述对象(descriptor)

// name 和age 虽然没有使用属性描述符来定义,但是他们也具备对应的特性的
// value: 赋值的 value
// configurable: true
// enumerable:true
// writable:true
var obj = {name: "why",age: 18
}
// 数据属性描述符
// 用了属性描述符,value 默认是 undefined,其他默认是 false
Object.defineProperty(obj, "address", {value: "北京市",// configurable:false 表示 这个属性不可删除/不可以重新定义属性描述符configurable: false,// enumerable 配置 该属性是否是可以枚举的,false 不可枚举的// 用 for in 遍历对象,会找不到 address,如果 是true 那就会找到addressenumerable: false,// writable表示 该属性是否可以被修改,false 表示 不可以修改,true 表示可以修改writable: false,
})
console.log(Object.getOwnPropertyDescriptors(obj));

4、es9

4.1 迭代器

后续补充

4.2 对象展开运算符

jses6 新特性,以及es7/8/9 或,常用特性相关推荐

  1. ES6/ES7/ES8/ES9/ES10常用特性和新特性最全总结

    ES6 ES6在ES5的基础上新增了一系列特性,这里仅列出常用特性 变量的改变,添加了块级作用域的概念 let声明变量(块级作用域),let是更完美的var,它声明的全局变量不是全局属性widow的变 ...

  2. Swfit 常用特性(Attribute)关键字

    Swfit 常用特性(Attribute)关键字 Swift中的Attribute相当于Java中的注解,但是可惜的是目前Swift不支持自定义Attribute Swfit的特性关键字一般用于声明或 ...

  3. vue-day02-vue常用特性

    文章目录 Vue常用特性 表单基本操作 表单修饰符 自定义指令 Vue.directive 注册全局指令 Vue.directive 注册全局指令 带参数 自定义指令局部指令 计算属性 compute ...

  4. [Vue.js] 基础 -- Vue常用特性

    Vue常用特性 常用特性概览 表单操作 自定义指令 计算属性 过滤器 侦听器 生命周期 表单操作 基于Vue的表单操作 Input 单行文本 textarea 多行文本 select 下拉多选 rad ...

  5. Vue学习笔记(一)—— 常用特性

    简介 Vue的常用特性其实也是Vue语法的一部分,只是为了学习方便,所以单独拿出来进行说明,学习上也显得更清晰. 对于基础部分,可用参考官网上的介绍. Vue 常用特性 表单操作 自定义指令 计算属性 ...

  6. Vue常用特性~非常详细哦,带源码资料

    下面是对Vue常用特性的整理,希望可以帮助到有需要的小伙伴~ 源码资料: 链接:https://pan.baidu.com/s/14rRYtUfXkO6mxUtCh4FCcA 提取码:e0sw 文章目 ...

  7. C++11特性及其它常用特性

    文章目录 C++11特性及其它常用特性 1. explicit 关键字 2. 左值和右值的概念 3. 函数返回值当引用 4. C++11 新增容器 - array array容器概念 array特点 ...

  8. [闪存2.1] NAND FLASH特性串烧 | 不了解闪存特性,你能用好闪存产品吗?

    声明 主页: 元存储的博客_CSDN博客 依公开知识及经验整理,如有误请留言. 个人辛苦整理,付费内容,禁止转载. 内容摘要 一.闪存的特性 二. 闪存的劣势及其解决机制 前言 为了利用好闪存, 发挥 ...

  9. vue基础之常用特性

    vue 常用特性 表单基本操作 获取单选框中的值 通过v-model <!---1. 两个单选框需要同时通过v-model 双向绑定 一个值 ----> <!---2. 每一个单选框 ...

  10. 我的世界java版特性_我的世界Java版特性展望直面会爆料

    在今年我的世界MineconEarth的Java版特性展望直面会上,官方人员曝光了非常多Java版未来会加入的特性,现在就让我们一起来了解一下Java版未来的更新计划吧! [我的世界pc版交流群1]欢 ...

最新文章

  1. Python中if语句练习题
  2. 【转载】linux环境变量PS1的简介
  3. 使用 CSS3 伪元素实现立体的照片堆叠效
  4. FMDB使用的数据库的三种形式
  5. 根据字段的不同内容分类汇总 - 球队的胜负次数统计
  6. Events are a bad idea?
  7. (error) LOADING Redis is loading the dataset in memory问题解决
  8. jQuery的DOM操作之取值/赋值(1)
  9. 【Linux】五分钟搞定 Linux 文档全部知识,就看这篇文章
  10. Mybatis的注解应用之关系映射
  11. c语言编程菜单流程图,C语言课程设计————写下流程图! 谢谢
  12. CHM电子书制作软件(CHM-Software)工具集锦简介
  13. 嵌入式Linux--MYS-6ULX-IOT--总目录
  14. 提升目标检测模型性能的tricks
  15. hdu-6130-Kolakoski
  16. 【DB笔试面试608】在Oracle中,如何使用STA来生成SQL Profile?
  17. 波形发生器的工作原理
  18. 提交 Merge Request 申请进行code review
  19. 微信H5端网页授权流程(在H5中的openid获取,网页绑定微信)
  20. 软件教父马丁.福勒的心灵鸡汤

热门文章

  1. 37岁被裁员,出来再找工作,大公司不愿要,无奈去小公司面试,HR的话扎心了
  2. 腾讯云配置密钥使用putty登录 PuTTY实现Windows向Linux上传文件
  3. 跨境电商账号矩阵运营方法论
  4. 浅谈网站的logo设计
  5. 云服务器是widows7系统,云服务器win7系统
  6. java 连接PLC 问题总结 Windows machine for DCOM access, so as to avoid such exceptions.  [0x00000005]
  7. 研发部软件开发国家标准
  8. Output输出缓存区大小只有1024KB,超过大小限制的就会被清除
  9. 中望3D 2021 插入基准面 - 2实体构面法
  10. VS将复制过来的文件或文件夹显示到解决方案管理