jses6 新特性,以及es7/8/9 或,常用特性
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 箭头函数
- 相比以前,有更简单的写法
- 箭头函数不绑定this,会捕获其所在上下文的this,作为自己的this
- 箭头函数是匿名函数,不能作为构造函数,不可以使用new命令,否则后抛出错误
- 箭头函数不绑定arguments
- 使用call,apply,bind并不会改变箭头函数中的this指向
- 箭头函数没有原型对象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 或,常用特性相关推荐
- ES6/ES7/ES8/ES9/ES10常用特性和新特性最全总结
ES6 ES6在ES5的基础上新增了一系列特性,这里仅列出常用特性 变量的改变,添加了块级作用域的概念 let声明变量(块级作用域),let是更完美的var,它声明的全局变量不是全局属性widow的变 ...
- Swfit 常用特性(Attribute)关键字
Swfit 常用特性(Attribute)关键字 Swift中的Attribute相当于Java中的注解,但是可惜的是目前Swift不支持自定义Attribute Swfit的特性关键字一般用于声明或 ...
- vue-day02-vue常用特性
文章目录 Vue常用特性 表单基本操作 表单修饰符 自定义指令 Vue.directive 注册全局指令 Vue.directive 注册全局指令 带参数 自定义指令局部指令 计算属性 compute ...
- [Vue.js] 基础 -- Vue常用特性
Vue常用特性 常用特性概览 表单操作 自定义指令 计算属性 过滤器 侦听器 生命周期 表单操作 基于Vue的表单操作 Input 单行文本 textarea 多行文本 select 下拉多选 rad ...
- Vue学习笔记(一)—— 常用特性
简介 Vue的常用特性其实也是Vue语法的一部分,只是为了学习方便,所以单独拿出来进行说明,学习上也显得更清晰. 对于基础部分,可用参考官网上的介绍. Vue 常用特性 表单操作 自定义指令 计算属性 ...
- Vue常用特性~非常详细哦,带源码资料
下面是对Vue常用特性的整理,希望可以帮助到有需要的小伙伴~ 源码资料: 链接:https://pan.baidu.com/s/14rRYtUfXkO6mxUtCh4FCcA 提取码:e0sw 文章目 ...
- C++11特性及其它常用特性
文章目录 C++11特性及其它常用特性 1. explicit 关键字 2. 左值和右值的概念 3. 函数返回值当引用 4. C++11 新增容器 - array array容器概念 array特点 ...
- [闪存2.1] NAND FLASH特性串烧 | 不了解闪存特性,你能用好闪存产品吗?
声明 主页: 元存储的博客_CSDN博客 依公开知识及经验整理,如有误请留言. 个人辛苦整理,付费内容,禁止转载. 内容摘要 一.闪存的特性 二. 闪存的劣势及其解决机制 前言 为了利用好闪存, 发挥 ...
- vue基础之常用特性
vue 常用特性 表单基本操作 获取单选框中的值 通过v-model <!---1. 两个单选框需要同时通过v-model 双向绑定 一个值 ----> <!---2. 每一个单选框 ...
- 我的世界java版特性_我的世界Java版特性展望直面会爆料
在今年我的世界MineconEarth的Java版特性展望直面会上,官方人员曝光了非常多Java版未来会加入的特性,现在就让我们一起来了解一下Java版未来的更新计划吧! [我的世界pc版交流群1]欢 ...
最新文章
- Python中if语句练习题
- 【转载】linux环境变量PS1的简介
- 使用 CSS3 伪元素实现立体的照片堆叠效
- FMDB使用的数据库的三种形式
- 根据字段的不同内容分类汇总 - 球队的胜负次数统计
- Events are a bad idea?
- (error) LOADING Redis is loading the dataset in memory问题解决
- jQuery的DOM操作之取值/赋值(1)
- 【Linux】五分钟搞定 Linux 文档全部知识,就看这篇文章
- Mybatis的注解应用之关系映射
- c语言编程菜单流程图,C语言课程设计————写下流程图! 谢谢
- CHM电子书制作软件(CHM-Software)工具集锦简介
- 嵌入式Linux--MYS-6ULX-IOT--总目录
- 提升目标检测模型性能的tricks
- hdu-6130-Kolakoski
- 【DB笔试面试608】在Oracle中,如何使用STA来生成SQL Profile?
- 波形发生器的工作原理
- 提交 Merge Request 申请进行code review
- 微信H5端网页授权流程(在H5中的openid获取,网页绑定微信)
- 软件教父马丁.福勒的心灵鸡汤
热门文章
- 37岁被裁员,出来再找工作,大公司不愿要,无奈去小公司面试,HR的话扎心了
- 腾讯云配置密钥使用putty登录 PuTTY实现Windows向Linux上传文件
- 跨境电商账号矩阵运营方法论
- 浅谈网站的logo设计
- 云服务器是widows7系统,云服务器win7系统
- java 连接PLC 问题总结 Windows machine for DCOM access, so as to avoid such exceptions. [0x00000005]
- 研发部软件开发国家标准
- Output输出缓存区大小只有1024KB,超过大小限制的就会被清除
- 中望3D 2021 插入基准面 - 2实体构面法
- VS将复制过来的文件或文件夹显示到解决方案管理