一、数组新增的扩展
1-1 扩展运算符
// ES6通过扩展元素符 ... 将一个数组转为用逗号分隔的参数序列console.log(...[1, 2, 3]) // 1 2 3console.log([...document.querySelectorAll('div')]) // [<div>, <div>, <div>]// 能够实现数组的浅拷贝const a1 = [1, 2];const a2 = [...a1];console.log(a2) // [1, 2]// 合并数组const a1 = [1, 2];const a2 = [3, 4];const a3 = [...a1, ...a2];console.log(a3) // [1, 2, 3, 4]// 扩展运算符可以与解构赋值结合起来,用于生成数组const [first, ...rest] = [1, 2, 3, 4, 5];console.log(first) // 1console.log(rest) // [2, 3, 4, 5]// 将字符串转为真正的数组console.log([...'hello']) // ['h', 'e', 'l', 'l', 'o']// 可以将定义了遍历器(Iterator)接口的对象转为数组let set = new Set(['a','b','c'])console.log(set) // Set(3) {'a', 'b', 'c'}console.log([...set]) // ['a', 'b', 'c']
1-2 构造函数 Array 新增的方法
Array.from() :可以将类似数组的对象和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)
// 基本用法let obj = {0: 'a',1: 'b',2: 'c',length: 3}console.log(Array.from(obj)) // ['a', 'b', 'c']// Array.from()第二个参数是一个函数,用来对每个元素进行处理,将处理后的值放入返回的数组console.log(Array.from(obj,(item) => item+item)) // ['aa', 'bb', 'cc']
Array.of():用于将一组值,转换为数组
// 基本用法console.log(Array.of(1, 2, 3)) // [1, 2, 3]// 没有参数的时候,返回一个空数组console.log(Array.of()) // []// 当参数只有一个的时候,实际上是指定数组的长度,所以说Array.of()参数值不能少于两个console.log(Array.of(3)) // [ , , ]
1-3 Array 实例对象新增的方法
copyWithin():将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组
// 参数如下arget(必需):从该位置开始替换数据。如果为负值,表示倒数。start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示从末尾开始计算。end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示从末尾开始计算。// 将从 3 号位直到数组结束的成员(4 和 5),复制到从 0 号位开始的位置,结果覆盖了原来的 1 和 2let arr = [1, 2, 3, 4, 5].copyWithin(0, 3)console.log(arr) // [4, 5, 3, 4, 5]
find():找出第一个符合条件的数组成员
// 参数是一个回调函数,接受三个参数依次为当前的值、当前的位置和原数组let a = [1, 2, 3, 4, 5].find(function(value, index, arr) {return value > 3;})console.log(a) // 4
findIndex():返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1
// 第一个参数是一个回调函数,接受三个参数依次为当前的值、当前的位置和原数组// 第二个参数是绑定回调函数的this对象let a = [1, 2, 3, 4, 5].findIndex(function(value, index, arr) {return value > 4;})console.log(a) // 4---------------------------------------------------------------function fn(value, index, arr){return value > this.age;}let arr = { age: 2 }let b = [1, 2, 3, 4, 5].findIndex(fn, arr)console.log(b) // 2
fill():使用给定值,填充一个数组
// 第一个参数是填充值,第二个和第三个参数分别是填充的起始位置和结束位置console.log(new Array(3).fill(0)) // [0, 0, 0]console.log(new Array(3).fill(0).fill(7, 1, 2)) // [0, 7, 0]
keys(),values(),entries(),
keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历
for(let key of ['a', 'b'].keys()){console.log(key)}// 0// 1for(let value of ['a', 'b'].values()){console.log(value)}// 'a'// 'b'for(let [key, value] of ['a', 'b'].entries()){console.log(key, value)}// 0 'a'// 1 'b'
includes():用于判断数组是否包含给定的值,返回一个布尔值,第二个参数表示搜索的起始位置,默认为0,
负数则表示倒数的位置
[1, 2, 3].includes(2) // true[1, 2, 3].includes(4) // false[1, 2, 3].includes(3, 3); // false[1, 2, 3].includes(3, -1); // true
flat():将数组扁平化处理,返回一个新数组,对原数据没有影响,默认只会“拉平”一层,如果想要“拉平”多层的嵌套数组,可以将flat()方法的参数写成一个整数,表示想要拉平的层数,默认为1
console.log([1, 2, [3, [4, 5]]].flat()) // [1, 2, 3, [4, 5]]console.log([1, 2, [3, [4, 5]]].flat(2)) // [1, 2, 3, 4, 5]
flatMap():对原数组的每个成员执行一个函数相当于执行Array.prototype.map(),然后对返回值组成的数组执行flat()方法。该方法返回一个新数组,不改变原数组,第二个参数,用来绑定遍历函数里面的this
// 等价于 [[2, 4], [3, 6], [4, 8]].flat()console.log([2, 3, 4].flatMap((x) => [x, x * 2])) // [2, 4, 3, 6, 4, 8]
1-4 数组的空位
数组的空位是指数组的某一个位置没有任何值,ES6 则是明确将空位转为 undefined ,包括Array.from、扩展运算符、copyWithin()、fill()、entries()、keys()、values()、find() 和 findIndex()
1-5 sort() 排序算法稳定性
const arr = ['peach','straw','apple','spork'];const stableSorting = (s1, s2) => {if (s1[0] < s2[0]) return -1;return 1;};arr.sort(stableSorting) // ["apple", "peach", "straw", "spork"]
二、对象新增的扩展
2-1 属性的简写
当对象键名与对应值名相等的时候,可以进行简写
const a = { b: b }// 等价于const a = { b }// 注意:简写的对象方法不能用作构造函数,否则会报错const obj = {f() {this.foo = 'bar';}};new obj.f() // 报错
2-2 属性名表达式
// ES6 允许字面量定义对象时,将表达式放在括号内let a = 'aaa'let b = {[a]: 'hello'}console.log(b['aaa']) // 'hello'// 表达式还可以用于定义方法名let obj = {['h' + 'ello']() {console.log('hello')}}obj.hello() // 'hello'// 属性名表达式与属性简写,不能同时使用,会报错const foo = 'bar';const bar = 'abc';const baz = { [foo] }; // 报错// 注意,属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串[object Object]const keyA = {a: 1}const objA = {[keyA]: 'valueA'};console.log(objA) // {[object Object]: 'valueA'}
2-3 super关键字
https://www.yuque.com/xiaotuzidehzy/euhezi/edy5n1
2-4 扩展运算符
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };console.log(x) // 1console.log(y) // 2console.log(z) // {a: 3, b: 4}// 扩展运算符配合解构赋值是浅拷贝let obj = { a: 1, b: 2 }let { ...x } = objconsole.log(x) // {a: 1, b: 2}// 等价于使用Object.assign()方法
2-5 属性的遍历
ES6 一共有 5 种方法可以遍历对象的属性
- for…in:循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)
 - Object.keys(obj):返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名
 - Object.getOwnPropertyNames(obj):返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名
 - Object.getOwnPropertySymbols(obj):返回一个数组,包含对象自身的所有 Symbol 属性的键名
 - Reflect.ownKeys(obj):返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举
 
属性遍历的次序规则
- 首先遍历所有数值键,按照数值升序排列
 - 其次遍历所有字符串键,按照加入时间升序排列
 - 最后遍历所有 Symbol 键,按照加入时间升序排
Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 })// ['2', '10', 'b', 'a', Symbol()]
2-6 对象新增的方法
https://www.yuque.com/xiaotuzidehzy/euhezi/pv5rg9三、函数新增的扩展
3-1 参数
```javascript // ES6允许为函数的参数设置默认值 
function log(x, y = ‘b’) { console.log(x, y) } log(‘a’) // ‘a’ ‘b’
// 函数的形参是默认声明的,不能使用let或const再次声明
function foo(x = 5) { let x = 1; // error const x = 2; // error }
// 参数默认值可以与解构赋值的默认值结合起来使用
function foo({x, y = 5}) { console.log(x, y) } foo({x: 1}) // 1 5 foo() // 报错,参数为对象的时候才能进行解构,否则变量x和y就不会生成
// 设置默认值避免报错
function foo({x, y = 5} = {}) { console.log(x, y) } foo() // undefined 5 foo(1) // undefined 5
// 参数默认值应该是函数的尾参数,如果不是非尾部的参数设置默认值,实际上这个参数是没发省略的 function f(x = 1, y) { console.log(x, y) } f(, 1) // 报错
<a name="x5V6P"></a>## 3-2 属性**函数的length属性将返回没有指定默认值的参数个数**```javascript(function (a) {}).length // 1(function (a = 5) {}).length // 0(function (a, b, c = 5) {}).length // 2// rest 参数也不会计入length属性(function(...args) {}).length // 0// 如果设置了默认值的参数不是尾参数,那么length属性也不再计入后面的参数了(function (a = 0, b, c) {}).length // 0(function (a, b = 1, c) {}).length // 1
函数的name属性返回该函数的函数名
var f = function () {};console.log(f.name)// "f"// 如果将一个具名函数赋值给一个变量,则 name 属性都返回这个具名函数原本的名字const bar = function baz() {};console.log(bar.name) // "baz"// Function构造函数返回的函数实例,name属性的值为anonymous(new Function).name // "anonymous"const f = new Function()console.log(f.name) // "anonymous"// bind返回的函数,name属性值会加上bound前缀function foo() {};foo.bind({}).name // "bound foo"
3-3 作用域
https://www.yuque.com/xiaotuzidehzy/euhezi/kb4iul
3-4 严格模式
只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式,否则会报错
// 报错function doSomething(a, b = a) {'use strict';// code}// 报错const doSomething = function ({a, b}) {'use strict';// code};// 报错const doSomething = (...a) => {'use strict';// code};const obj = {// 报错doSomething({a, b}) {'use strict';// code}};
3-5 箭头函数
let p = {a: function () {var obj = {b: () => {console.log(this)},}obj.b()}}p.a() // {a: ƒ} 函数执行上下文的this值// 箭头函数不绑定this, 它会捕获其定义时的位置上下文的this值, 作为自己的this值
