一、ES6相关概念
1.1什么是ES6
1.1.1简介
ES6, 全称 ECMAScript 6.0 ,是 JavaScript 的下一个版本标准,2015.06 发版。
ES6 主要是为了解决 ES5 的先天不足,比如 JavaScript 里并没有类的概念,但是目前浏览器的 JavaScript 是 ES5 版本,大多数高版本的浏览器也支持 ES6,不过只实现了 ES6 的部分特性和功能。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gglX4dot-1650377776745)(images/es-version.png)]
1.2为什么使用 ES6 ?
每一次标准的诞生都意味着语言的完善,功能的加强。JavaScript语言本身也有一些令人不满意的地方。
-
变量提升特性增加了程序运行时的不可预测性
-
语法过于松散,实现相同的功能,不同的人可能会写出不同的代码
(function(){ var num=10; })(); (function(){ var num=100; })();
1.3ES6 的目标与愿景
- 成为更好编写的开发语言有以下目标。
- 适应更复杂的应用;实现代码库之间的共享;不断迭代维护新版本。
二、ES6新增语法
2.1.let
ES6中新增了用于声明变量的关键字
2.1.1.let声明的变量只在所处于的块级有效
if (true) {
let a = 10;
}
console.log(a) // a is not defined
**注意:**使用let关键字声明的变量才具有块级作用域,使用var声明的变量不具备块级作用域特性。
2.1.2.不存在变量提升
console.log(a); // a is not defined
let a = 20;
2.1.3.暂时性死区
利用let声明的变量会绑定在这个块级作用域,不会受外界的影响
var tmp = 123;
if (true) {
tmp = 'abc';
let tmp;
}
2.1.4经典面试题
var arr = [];
for (var i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0]();
arr[1]();
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y3V0gfIr-1650377776747)(images/let面试题.png)]
**经典面试题图解:**此题的关键点在于变量i是全局的,函数执行时输出的都是全局作用域下的i值。
let arr = [];
for (let i = 0; i < 2; i++) {
arr[i] = function () {
console.log(i);
}
}
arr[0]();
arr[1]();
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xUC69biB-1650377776748)(images/let面试题2.png)]
**经典面试题图解:**此题的关键点在于每次循环都会产生一个块级作用域,每个块级作用域中的变量都是不同的,函数执行时输出的是自己上一级(循环产生的块级作用域)作用域下的i值.
for (var i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i); //5个5
}, 100)
}
for (let i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i); //0,1,2,3,4
}, 100)
}
for (var i = 0; i < 5; i++) {
setTimeout((function (num) {
console.log(num); //0,1,2,3,4
})(i), 100)
}
2.1.5小结
- let关键字就是用来声明变量的
- 使用let关键字声明的变量具有块级作用域
- 在一个大括号中 使用let关键字声明的变量才具有块级作用域 var关键字是不具备这个特点的
- 防止循环变量变成全局变量
- 使用let关键字声明的变量没有变量提升
- 使用let关键字声明的变量具有暂时性死区特性
2.2const
声明常量,常量就是值(内存地址)不能变化的量
2.2.1.具有块级作用域
if (true) {
const a = 10;
}
console.log(a) // a is not defined
2.2.2声明常量时必须赋值
const PI; // Missing initializer in const declaration
2.2.3常量赋值后,值不能修改
const PI = 3.14;
PI = 3.1415; // Assignment to constant variable.
2.2.4小结
- const声明的变量是一个常量
- 既然是常量不能重新进行赋值,如果是基本数据类型,不能更改值,如果是复杂数据类型,不能更改地址值
- 声明 const时候必须要给定值
2.3let、const、var 的区别(面试题)
- 使用 var 声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象
- 使用 let 声明的变量,其作用域为该语句所在的代码块内,不存在变量提升
- 使用 const 声明的是常量,在后面出现的代码中不能再修改该常量的值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CSMbKuo4-1650377776749)(images/var&let&const区别.png)]
三、解构赋值
3.1概述
解构赋值是对赋值运算符的扩展。(运算符±*/%)
他是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。
在代码书写上简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。
ES6中允许从数组中提取值,按照对应位置,对变量赋值,对象也可以实现解构
3.2解构模型
在解构中,有下面两部分参与:
- 解构的源,解构赋值表达式的右边部分。
- 解构的目标,解构赋值表达式的左边部分。
3.3.数组解构
3.3.1基本
let [a, b, c] = [1, 2, 3];
// a = 1
// b = 2
// c = 3
3.3.2可嵌套
let [a, [[b], c]] = [1, [[2], 3]];
// a = 1
// b = 2
// c = 3
3.3.3可忽略
let [a, , b] = [1, 2, 3];
// a = 1
// b = 3
3.3.4不完全结构
let [a = 1, b] = []; // a = 1, b = undefined
3.3.5剩余运算符
let [a, ...b] = [1, 2, 3];
//a = 1
//b = [2, 3]
3.3.6字符串等
在数组的解构中,解构的目标若为可遍历对象,皆可进行解构赋值。可遍历对象即实现 Iterator 接口的数据。
let [a, b, c, d, e] = 'hello';
// a = 'h'
// b = 'e'
// c = 'l'
// d = 'l'
// e = 'o'
3.3.7解构默认值
let [a = 2] = [undefined]; // a = 2
当解构模式有匹配结果,且匹配结果是 undefined 时,会触发默认值作为返回结果。
let [a = 3, b = a] = []; // a = 3, b = 3
let [a = 3, b = a] = [1]; // a = 1, b = 1
let [a = 3, b = a] = [1, 2]; // a = 1, b = 2
- a 与 b 匹配结果为 undefined ,触发默认值:a = 3; b = a =3
- a 正常解构赋值,匹配结果:a = 1,b 匹配结果 undefined ,触发默认值:b = a =1
- a 与 b 正常解构赋值,匹配结果:a = 1,b = 2
3.4.对象解构
3.4.1基本
let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
// foo = 'aaa'
// bar = 'bbb'
let { baz : foo } = { baz : 'ddd' };
// foo = 'ddd'
3.4.2可嵌套可忽略
let obj = {p: ['hello', {y: 'world'}] };
let {p: [x, { y }] } = obj;
// x = 'hello'
// y = 'world'
let obj = {p: ['hello', {y: 'world'}] };
let {p: [x, { }] } = obj;
// x = 'hello'
3.4.3不完全解构
let obj = {p: [{y: 'world'}] };
let {p: [{ y }, x ] } = obj;
// x = undefined
// y = 'world'
3.4.4剩余运算符
let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40};
// a = 10
// b = 20
// rest = {c: 30, d: 40}
3.4.5解构默认值
let {a = 10, b = 5} = {a: 3};
// a = 3; b = 5;
let {a: aa = 10, b: bb = 5} = {a: 3};
// aa = 3; bb = 5;
3.5.小结
- 解构赋值就是把数据结构分解,然后给变量进行赋值
- 如果解构不成功,变量跟数值个数不匹配的时候,变量的值为undefined
- 数组解构用中括号包裹,多个变量用逗号隔开,对象解构用花括号包裹,多个变量用逗号隔开
- 利用解构赋值能够让我们方便的去取对象中的属性跟方法
四、ES6 Symbol
4.1概述
ES6 引入了一种新的原始数据类型 Symbol ,表示独一无二的值,最大的用法是用来定义对象的唯一属性名。
ES6 数据类型除了 Number 、 String 、 Boolean 、 Object、 Null 和 Undefined ,还新增了 Symbol 。
- 数据类型有哪些?
- typeof返回的类型有那些?
- typeof null —》object
4.2基本用法
Symbol 函数栈不能用 new 命令,因为 Symbol 是原始数据类型,不是对象。可以接受一个字符串作为参数,为新创建的 Symbol 提供描述,用来显示在控制台或者作为字符串的时候使用,便于区分。
let sy = Symbol("KK");
console.log(sy); // Symbol(KK)
typeof(sy); // "symbol"
// 相同参数 Symbol() 返回的值不相等
let sy1 = Symbol("kk");
sy === sy1; // false
用法
由于每一个 Symbol 的值都是不相等的,所以 Symbol 作为对象的属性名,可以保证属性不重名
五、ES6 Map 与 Set
5.1Map 对象
Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。
5.2Maps 和 Objects 的区别(面试题)
var obj={
username:"好谷",
123:"就业力" //错误写法
}
- 一个 Object 的键只能是字符串或者 Symbols,但一个 Map 的键可以是任意值。
- Map 中的键值是有序的(FIFO 原则),而添加到对象中的键则不是。
- Map 的键值对个数可以从 size 属性获取,而 Object 的键值对个数只能手动计算。
- Object 都有自己的原型,原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。
5.3Map 中的 key
5.3.1key 是字符串
var myMap = new Map();
var keyString = "a string";
myMap.set(keyString, "和键'a string'关联的值");
myMap.get(keyString); // "和键'a string'关联的值"
myMap.get("a string"); // "和键'a string'关联的值"
// 因为 keyString === 'a string'
5.3.2key 是对象
var myMap = new Map();
var keyObj = {},
myMap.set(keyObj, "和键 keyObj 关联的值");
myMap.get(keyObj); // "和键 keyObj 关联的值"
myMap.get({}); // undefined, 因为 keyObj !== {}
5.3.3key 是函数
var myMap = new Map();
var keyFunc = function () {}, // 函数
myMap.set(keyFunc, "和键 keyFunc 关联的值");
myMap.get(keyFunc); // "和键 keyFunc 关联的值"
myMap.get(function() {}) // undefined, 因为 keyFunc !== function () {}
5.3.4key 是 NaN
var myMap = new Map();
myMap.set(NaN, "not a number");
myMap.get(NaN); // "not a number"
var otherNaN = Number("foo");
myMap.get(otherNaN); // "not a number"
虽然 NaN 和任何值甚至和自己都不相等(NaN !== NaN 返回true),NaN作为Map的键来说是没有区别的。
5.4Map 的迭代
对 Map 进行遍历 for…of和forEach()
Set 对象
Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
Set 中的特殊值
Set 对象存储的值总是唯一的,所以需要判断两个值是否恒等。有几个特殊值需要特殊对待:
- +0 与 -0 在存储判断唯一性的时候是恒等的,所以不重复;
- undefined 与 undefined 是恒等的,所以不重复;
- NaN 与 NaN 是不恒等的,但是在 Set 中只能存一个,不重复。
let mySet = new Set();
mySet.add(1); // Set(1) {1}
mySet.add(5); // Set(2) {1, 5}
Set 对象作用
1.数组去重
var mySet = new Set([1, 2, 3, 4, 4]);
[...mySet]; // [1, 2, 3, 4]
2.合并数组
var a = new Set([1, 2, 3]);
var b = new Set([4, 3, 2]);
var union = new Set([...a, ...b]); // {1, 2, 3, 4}
六、ES6 Reflect 与 Proxy
6.1概述
Proxy 与 Reflect 是 ES6 为了操作对象引入的 API 。
Proxy 可以对目标对象的读取、函数调用等操作进行拦截,然后进行操作处理。它不直接操作对象,而是像代理模式,通过对象的代理对象进行操作,在进行这些操作时,可以添加一些需要的额外操作。
Reflect 可以用于获取目标对象的行为,它与 Object 类似,但是更易读,为操作对象提供了一种更优雅的方式。它的方法与 Proxy 是对应的。
6.2基本用法
6.2.1Proxy
一个 Proxy 对象由两个部分组成: target 、 handler 。在通过 Proxy 构造函数生成实例对象时,需要提供这两个参数。 target 即目标对象, handler 是一个对象,声明了代理 target 的指定行为。
let target = {
name: 'Tom',
age: 24
}
let handler = {
get: function(target, key) {
console.log('getting '+key);
return target[key]; // 不是target.key
},
set: function(target, key, value) {
console.log('setting '+key);
target[key] = value;
}
}
let proxy = new Proxy(target, handler)
proxy.name // 实际执行 handler.get
proxy.age = 25 // 实际执行 handler.set
6.2.2Reflect(了解)
ES6 中将 Object 的一些明显属于语言内部的方法移植到了 Reflect 对象上(当前某些方法会同时存在于 Object 和 Reflect 对象上),未来的新方法会只部署在 Reflect 对象上。
Reflect 对象对某些方法的返回结果进行了修改,使其更合理。
Reflect 对象使用函数的方式实现了 Object 的命令式操作。
静态方法
Reflect.get(target, name, receiver)
查找并返回 target 对象的 name 属性。
let exam = {
name: "Tom",
age: 24,
get info(){
return this.name + this.age;
}
}
Reflect.get(exam, 'name'); // "Tom"
// 当 target 对象中存在 name 属性的 getter 方法, getter 方法的 this 会绑定 // receiver
let receiver = {
name: "Jerry",
age: 20
}
Reflect.get(exam, 'info', receiver); // Jerry20
// 当 name 为不存在于 target 对象的属性时,返回 undefined
Reflect.get(exam, 'birth'); // undefined
// 当 target 不是对象时,会报错
Reflect.get(1, 'name'); // TypeError
6.2.3组合使用
Reflect 对象的方法与 Proxy 对象的方法是一一对应的。所以 Proxy 对象的方法可以通过调用 Reflect 对象的方法获取默认行为,然后进行额外操作。
let exam = {
name: "Tom",
age: 24
}
let handler = {
get: function(target, key){
console.log("getting "+key);
return Reflect.get(target,key);
},
set: function(target, key, value){
console.log("setting "+key+" to "+value)
Reflect.set(target, key, value);
}
}
let proxy = new Proxy(exam, handler)
proxy.name = "Jerry"
proxy.name
// setting name to Jerry
// getting name
// "Jerry"
七、ES6 字符串
7.1.拓展的方法
7.1.1.子串的识别
ES6 之前判断字符串是否包含子串,用 indexOf 方法,ES6 新增了子串的识别方法。
- includes():返回布尔值,判断是否找到参数字符串。
- startsWith():返回布尔值,判断参数字符串是否在原字符串的头部。
- endsWith():返回布尔值,判断参数字符串是否在原字符串的尾部。
以上三个方法都可以接受两个参数,需要搜索的字符串,和可选的搜索起始位置索引。
let string = "apple,banana,orange";
string.includes("banana"); // true
string.startsWith("apple"); // true
string.endsWith("apple"); // false
string.startsWith("banana",6) // true
注意:
- 这三个方法只返回布尔值,如果需要知道子串的位置,还是得用 indexOf 和 lastIndexOf 。
- 这三个方法如果传入了正则表达式而不是字符串,会抛出错误。而 indexOf 和 lastIndexOf 这两个方法,它们会将正则表达式转换为字符串并搜索它。
7.1.2.字符串重复
repeat():返回新的字符串,表示将字符串重复指定次数返回。
console.log("Hello,".repeat(2)); // "Hello,Hello,"
7.1.3.字符串补全
- padStart:返回新的字符串,表示用参数字符串从头部(左侧)补全原字符串。
- padEnd:返回新的字符串,表示用参数字符串从尾部(右侧)补全原字符串。
以上两个方法接受两个参数,第一个参数是指定生成的字符串的最小长度,第二个参数是用来补全的字符串。如果没有指定第二个参数,默认用空格填充。
console.log("h".padStart(5,"o")); // "ooooh"
console.log("h".padEnd(5,"o")); // "hoooo"
console.log("h".padStart(5)); // " h"
7.1.4模板字符串
模板字符串相当于加强版的字符串,用反引号 `,除了作为普通字符串,还可以用来定义多行字符串,还可以在字符串中加入变量和表达式。
let string = `Hello'\n'world`;
console.log(string);
// "Hello'
// 'world"
//模板字符串 ``反引号
var num = 123
var fn = function () {
return "hello"
}
let str66 = "hello \n everyone"
console.log(str66);
let str666 = `hello everyone ${num + 10} ${fn()}`
console.log(str666);
let str2=`hello`
八、ES6 数值
8.1数值的表示
二进制表示法新写法: 前缀 0b 或 0B 。
console.log(0b11 === 3); // true
console.log(0B11 === 3); // true
八进制表示法新写法: 前缀 0o 或 0O 。
console.log(0o11 === 9); // true
console.log(0O11 === 9); // true
8.2方法
Number 对象新方法
Number.isFinite()
- 用于检查一个数值是否为有限的( finite ),即不是 Infinity
console.log( Number.isFinite(1)); // true
console.log( Number.isFinite(0.1)); // true
// NaN 不是有限的
console.log( Number.isFinite(NaN)); // false
console.log( Number.isFinite(Infinity)); // false
console.log( Number.isFinite(-Infinity)); // false
// Number.isFinate 没有隐式的 Number() 类型转换,所有非数值都返回 false
console.log( Number.isFinite('foo')); // false
console.log( Number.isFinite('15')); // false
console.log( Number.isFinite(true)); // false
Number.isNaN()
用于检查一个值是否为 NaN 。
console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN('true'/0)); // true
// 在全局的 isNaN() 中,以下皆返回 true,因为在判断前会将非数值向数值转换
// 而 Number.isNaN() 不存在隐式的 Number() 类型转换,非 NaN 全部返回 false
Number.isNaN("NaN"); // false
Number.isNaN(undefined); // false
Number.isNaN({}); // false
Number.isNaN("true"); // false
8.3.双曲函数方法
- Math.sinh(x): 用于计算双曲正弦。
- Math.cosh(x): 用于计算双曲余弦。
- Math.tanh(x): 用于计算双曲正切。
- Math.asinh(x): 用于计算反双曲正弦。
- Math.acosh(x): 用于计算反双曲余弦。
- Math.atanh(x): 用于计算反双曲正切。
8.4.指数运算符
1 ** 2; // 1
// 右结合,从右至左计算
2 ** 2 ** 3; // 256
// **=
let exam = 2;
exam ** = 2; // 4
九、ES6 对象
9.1属性的简洁表示法
const age = 12;
const name = "Amy";
const person = {age, name};
person //{age: 12, name: "Amy"}
//等同于
const person = {age: age, name: name}
9.2方法名也可以简写
const person = {
sayHi(){
console.log("Hi");
}
}
person.sayHi(); //"Hi"
//等同于
const person = {
sayHi:function(){
console.log("Hi");
}
}
person.sayHi();//"Hi"
9.2.3属性名表达式
ES6允许用表达式作为属性名,但是一定要将表达式放在方括号内。
const obj = {
["he"+"llo"](){
return "Hi";
}
}
obj.hello(); //"Hi"
- 注意点:属性的简洁表示法和属性名表达式不能同时使用,否则会报错。
const hello = "Hello";
const obj = {
[hello]
};
obj //SyntaxError: Unexpected token }
const hello = "Hello";
const obj = {
[hello+"2"]:"world"
};
obj //{Hello2: "world"}
9.2.4对象的拓展运算符
拓展运算符(…)用于取出参数对象所有可遍历属性然后拷贝到当前对象。
- 基本用法
let person = {name: "Amy", age: 15};
let someone = { ...person };
someone; //{name: "Amy", age: 15}
- 可用于合并两个对象
let age = {age: 15};
let name = {name: "Amy"};
let person = {...age, ...name};
person; //{age: 15, name: "Amy"}
- 注意点
自定义的属性和拓展运算符对象里面属性的相同的时候:自定义的属性在拓展运算符后面,则拓展运算符对象内部同名的属性将被覆盖掉。
let person = {name: "Amy", age: 15};
let someone = { ...person, name: "Mike", age: 17};
someone; //{name: "Mike", age: 17}
自定义的属性在拓展运算度前面,则变成设置新对象默认属性值。
let person = {name: "Amy", age: 15};
let someone = {name: "Mike", age: 17, ...person};
someone; //{name: "Amy", age: 15}
拓展运算符后面是空对象,没有任何效果也不会报错。
let a = {...{}, a: 1, b: 2};
a; //{a: 1, b: 2}
拓展运算符后面是null或者undefined,没有效果也不会报错。
let b = {...null, ...undefined, a: 1, b: 2};
b; //{a: 1, b: 2}
9.2.5对象的新方法
Object.assign(target, source_1, ···)
用于将源对象的所有可枚举属性复制到目标对象中。
let target = {a: 1};
let object2 = {b: 2};
let object3 = {c: 3};
Object.assign(target,object2,object3);
// 第一个参数是目标对象,后面的参数是源对象
target; // {a: 1, b: 2, c: 3}
- 如果目标对象和源对象有同名属性,或者多个源对象有同名属性,则后面的属性会覆盖前面的属性。
- 如果该函数只有一个参数,当参数为对象时,直接返回该对象;当参数不是对象时,会先将参数转为对象然后返回。
Object.assign(3); // Number {3}
typeof Object.assign(3); // "object"
因为 null 和 undefined 不能转化为对象,所以会报错:
Object.assign(null); // TypeError: Cannot convert undefined or null to object
Object.assign(undefined); // TypeError: Cannot convert undefined or null to object
当参数不止一个时,null 和 undefined 不放第一个,即不为目标对象时,会跳过 null 和 undefined ,不报错
Object.assign(1,undefined); // Number {1}
Object.assign({a: 1},null); // {a: 1}
Object.assign(undefined,{a: 1}); // TypeError: Cannot convert undefined or null to object
- 注意点
assign 的属性拷贝是浅拷贝:
let sourceObj = { a: { b: 1}};
let targetObj = {c: 3};
Object.assign(targetObj, sourceObj);
targetObj.a.b = 2;
sourceObj.a.b; // 2
同名属性替换
targetObj = { a: { b: 1, c:2}};
sourceObj = { a: { b: "hh"}};
Object.assign(targetObj, sourceObj);
targetObj; // {a: {b: "hh"}}
数组的处理
Object.assign([2,3], [5]); // [5,3]
会将数组处理成对象,所以先将 [2,3] 转为 {0:2,1:3} ,然后再进行属性复制,所以源对象的 0 号属性覆盖了目标对象的 0。
Object.is(value1, value2)
用来比较两个值是否严格相等,与(===)基本类似。
Object.is("q","q"); // true
Object.is(1,1); // true
Object.is([1],[1]); // false
Object.is({q:1},{q:1}); // false
十、ES6 数组
10.1数组创建
- Array.of()将参数中所有值作为元素形成数组。
console.log(Array.of(1, 2, 3, 4)); // [1, 2, 3, 4]
// 参数值可为不同类型
console.log(Array.of(1, '2', true)); // [1, '2', true]
// 参数为空时返回空数组
console.log(Array.of()); // []
- Array.from()将类数组对象或可迭代对象转化为数组。
// 参数为数组,返回与原数组一样的数组
console.log(Array.from([1, 2])); // [1, 2]
// 参数含空位
console.log(Array.from([1, , 3])); // [1, undefined, 3]
10.2扩展的方法
- find()查找数组中符合条件的元素,若有多个符合条件的元素,则返回第一个元素。
- findIndex()查找数组中符合条件的元素索引,若有多个符合条件的元素,则返回第一个元素索引。
- fill() 将一定范围索引的数组元素内容填充为单个指定的值。
- copyWithin() 将一定范围索引的数组元素修改为此数组另一指定范围索引的元素。
- entries()遍历键值对。
- keys()遍历键名。
- values()遍历键值。
- includes()数组是否包含指定值。
- flat()嵌套数组转一维数组
- flatMap()先对数组中每个元素进行了的处理,再对数组执行 flat() 方法。
10.3扩展运算符
- 复制数组
let arr = [1, 2],
arr1 = [...arr];
console.log(arr1); // [1, 2]
// 数组含空位
let arr2 = [1, , 3],
arr3 = [...arr2];
console.log(arr3); [1, undefined, 3]
- 合并数组
console.log([...[1, 2],...[3, 4]]); // [1, 2, 3, 4]
, 3, 4)); // [1, 2, 3, 4]
// 参数值可为不同类型
console.log(Array.of(1, ‘2’, true)); // [1, ‘2’, true]
// 参数为空时返回空数组
console.log(Array.of()); // []
- Array.from()将类数组对象或可迭代对象转化为数组。
```js
// 参数为数组,返回与原数组一样的数组
console.log(Array.from([1, 2])); // [1, 2]
// 参数含空位
console.log(Array.from([1, , 3])); // [1, undefined, 3]
10.2扩展的方法
- find()查找数组中符合条件的元素,若有多个符合条件的元素,则返回第一个元素。
- findIndex()查找数组中符合条件的元素索引,若有多个符合条件的元素,则返回第一个元素索引。
- fill() 将一定范围索引的数组元素内容填充为单个指定的值。
- copyWithin() 将一定范围索引的数组元素修改为此数组另一指定范围索引的元素。
- entries()遍历键值对。
- keys()遍历键名。
- values()遍历键值。
- includes()数组是否包含指定值。
- flat()嵌套数组转一维数组
- flatMap()先对数组中每个元素进行了的处理,再对数组执行 flat() 方法。
10.3扩展运算符
- 复制数组
let arr = [1, 2],
arr1 = [...arr];
console.log(arr1); // [1, 2]
// 数组含空位
let arr2 = [1, , 3],
arr3 = [...arr2];
console.log(arr3); [1, undefined, 3]
- 合并数组
console.log([...[1, 2],...[3, 4]]); // [1, 2, 3, 4]