- forEach()
- for…of
- for…in
- Object.values()
- Object.keys()
- Object.entries()
- indexOf()
- setTimeout()
- apply/call
- Math.floor()向下取整
- Math.ceil()向上取整
- Math.random()四舍五入
- parseInt 取整
- Objcet.assign()
- toUpperCase()
- toFixed(n)
- toString()
- split() — 字符串
- join
- Array.from()
- reduce()
- Number
- isNaN
- parseFloat
- break 和 continue 语句
- JSON.parse()
- JSON.stringify()
- every
- some
- filter
- map
- object.defineProperty()
- instanceof
- parseInt
- charCodeAt
- while
- setInterval
- find
- findIndex()
- 逻辑运算符 &&
- splice
- Array.from
- Set
- instanceof
- sort
- switch case
- Object.create()">Object.create()
- concat
- 稀松数组
- addEventListener 函数
- Object.keys
- hasOwnProperty
- Map.set()">Map.set()
- flat ">flat
forEach()
forEach()方法对数组中的每一个元素执行一次提供的函数。
用于调用数组的每个元素,并将元素传递给回调函数。
注意:forEach()对于空数组是不会执行回调函数的。
返回值:undefined
例子:let arr = ['a','b','c']arr.forEach(ele=>console.log(ele)) //a b c 'string'类型
for…of
在可迭代对象(包括Array Map String等等) 上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句。
语法:for(variable of iterable){//statements}variable 在每次迭代中 将不同属性的值分配给变量iterable 被迭代枚举其属性的对象const arr = ['a','b','c']for(let element of arr){console.log(element)}
for…in
以任意顺序遍历一个对象的除Symbol以外的可枚举属性。为遍历对象属性而构建。
var obj = {a:1, b:2, c:3};for (var prop in obj) {console.log("obj." + prop + " = " + obj[prop]);}// Output:// "obj.a = 1"// "obj.b = 2"// "obj.c = 3"
Object.values()
Object.values() 方法返回一个给定对象自身的所有可枚举属性值的数组,值得顺序与使用for…in 循环的顺序相同。(区别在于 for in 循环会枚举原型链中的属性)
var obj = { foo: 'bar', baz: 42 };console.log(Object.values(obj)); // ['bar', 42]// array like object with random key ordering// when we use numeric keys, the value returned in a numerical order according to the keysvar an_obj = { 100: 'a', 2: 'b', 7: 'c' };console.log(Object.values(an_obj)); // ['b', 'c', 'a']// non-object argument will be coerced to an objectconsole.log(Object.values('foo')); // ['f', 'o', 'o']
Object.keys()
Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致。
// simple arrayvar arr = ['a', 'b', 'c'];console.log(Object.keys(arr)); // console: ['0', '1', '2']// array like objectvar obj = { 0: 'a', 1: 'b', 2: 'c' };console.log(Object.keys(obj)); // console: ['0', '1', '2']// array like object with random key orderingvar anObj = { 100: 'a', 2: 'b', 7: 'c' };console.log(Object.keys(anObj)); // console: ['2', '7', '100']
Object.entries()
Object.entries() 方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)
const obj = { foo: 'bar', baz: 42 };console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]// array like object with random key orderingconst anObj = { 100: 'a', 2: 'b', 7: 'c' };console.log(Object.entries(anObj)); // [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ]// iterate through key-value gracefullyconst obj = { a: 5, b: 7, c: 9 };for (const [key, value] of Object.entries(obj)) {console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"}// Or, using array extrasObject.entries(obj).forEach(([key, value]) => {console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"});
indexOf()
indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1
const arr = [1,2,3,4,5]console.log(arr.indexOf(1)) //0 第0位console.log(arr.indexOf(8)) //-1
setTimeout()
setTimeout 传参数
除了前面两个参数 setTimeout 还允许添加更多的参数,它们将被传入推迟执行的函数(回调函数)
apply/call
区别所在: apply:数组形式 / call:参数列表
func.apply(thisArg, [argsArray])
注: thisArg 在func函数运行时使用的this值.可以为null会自动替换指向全局对象,
注意:返回值 调用有指定this和参数的函数的结果
var a = function(){console.log(1)}console.log(a.apply(this)) //1 undefined 这里的undefined 就是a函数的返回值
var a = function(){console.log(1)return 1}console.log(a.apply(this)) //1 1
实际应用:将类数组对象转换为数组
function exam(a, b, c, d, e) {console.log(arguments)var arg = [].slice.call(arguments)// var arg = Array.from(arguments) //方法二console.log(arg)}exam(1, 2, 3, 4)
Math.floor()向下取整
Math.floor( 45.95);// 45
Math.ceil()向上取整
console.log(Math.ceil(.95));// 1
Math.random()四舍五入
parseInt 取整
将字符串转化为整数,如果字符串不以整数开头,将返回NaN
在第一个非整数位停止解析,并且返回前面读到的所有整数var a = 1.8;var b = parseInt(a)console.log(b) //1
Objcet.assign()
Object.assign()方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
语法:Object.assign(target,...sources)参数 :target: 目标对象(比如说我定义了一个 copy 为空,我要把obj复制过来,此时copy 就是目标对象)sources: 源对象返回值: 目标对象补充 : target可以理解为 新拷贝的对象例子 复制一个对象const obj = { a: 1 };const copy = Object.assign({}, obj);console.log(copy); // { a: 1 }如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。let obj = {a:1}let obj2 = {a:2}let copy = Object.assign(obj2,obj)console.log(copy) //{a: 1}
Object.assign()拷贝的是属性值。假如源对象的属性值是一个对象的引用,那么它也只指向那个引用。也就是源对象中的对象的引用,那么这个是不会改变的,也就是浅拷贝例子说明const obj = {a: 1,b:{name:"chu"}};const copy = Object.assign({}, obj);copy.b.name = "zhangsan"copy.a="2"console.log(obj);console.log(copy)

// Deep CloneJSON.stringify 类型 字符串JSON.parse 类型 Objectobj1 = { a: 0 , b: { c: 0}};let obj3 = JSON.parse(JSON.stringify(obj1));obj1.a = 4;obj1.b.c = 4;console.log(JSON.stringify(obj3)); // { a: 0, b: { c: 0}}
文档 : http://es6.ruanyifeng.com/#docs/object-methods
https://juejin.im/post/5c31e5c4e51d45524975d05a#heading-0
常见用途:
1)为对象添加属性(不会 )
class Point {constructor(x, y) {Object.assign(this, {x, y});}}上面方法通过Object.assign方法,将x属性和y属性添加到Point类的对象实例。
2)克隆对象
(不会保持origin 的属性特性(可写 可枚举等 ))
function clone(origin){return Object.assign({}, origin);}
toUpperCase()
str.toUpperCase() 返回一个大写的字符串let str = "Hello";alert( str.toUpperCase() ); // HELLO
toFixed(n)
let n = 1.23456;alert( n.toFixed(2) ); // 1.23
toString()
toString() 方法返回一个表示该对象的字符串
var num = 15num.toString() //15typeof a //string
每个对象都有一个toString() 方法,toString()方法被每个Object 对象继承。
var o = new Object();o.toString(); // returns [object Object]
split() — 字符串
使用指定的分隔符字符串将一个String对象分割成字符串数组
let str = 'chu'console.log(str.split("")) // ["c", "h", "u"]
join
用于把数组中的所有元素放入一个字符串
数组反转var a = "hello"a.split("").reverse().join("") //olleh
Array.from()
从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例
console.log(Array.from('foo'));// ["f", "o", "o"]
补充 该 方法会将一个可迭代对象(如字符串)转换为数组:
let a = "hello"Array.from(a)=> 等同于[...a]
ES6 去重
var arr =[1,2,3,4,5,6,3,2,3]function unique(arr){return Array.from(new Set(arr))}console.log(unique(arr))

reduce()
arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
**accumulator**
累计器累计回调的返回值; 它是上一次调用回调时返回的累积值
currentValue
数组中正在处理的元素。
index 可选
数组中正在处理的当前元素的索引。 如果提供了initialValue,则起始索引号为0,否则从索引1起始。
array可选
调用reduce()的数组
reduce() 方法对数组中的每个元素执行一个由你提供的reduce函数(升序执行),将其结果汇总为单个返回值
[x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)也就是先将 1 2项的值进行操作,可以是 加 或者是 做其它处理,然后所获取的值在与第3项值 进行操作
let arr = [1,2,3,4]let reducer = (a,b)=>a+bconsole.log(arr.reduce(reducer)) //10
去重应用
var arr =[1,2,3,4,5,5,5]var res = arr.reduce(function(pre,cur){if(!pre.includes(cur)){return pre.concat(cur)}else{return pre}},[])console.log(res)
Number
Number 对象主要用于
- 如果参数无法被转换为数字 则返回NaN
isNaN
isNaN()函数用来确定一个值是否为NaNNaN不能通过相等操作符(== 和 ===)来判断 ,因为 NaN == NaN 和 NaN === NaN 都会返回 false
如果函数的参数不是Number类型,那么会将参数转换为数值在进行与NaN的判断. 空字符串和布尔值分别会被强制转换为数值 0 和 1
0/0 => NaNisNaN("") //false 空字符串被转换成0isNaN(" ") //包含空格的字符串被转换为0
parseFloat
会被解析成浮点数,如果不能则会返回NaN
parseFloat(true) //NaN
break 和 continue 语句
break 语句会立即退出循环,强制继续执行循环后面的语句
containue 立即退出循环 但退出循环后会从循环的顶部继续执行
JSON.parse()
补充(2021.8.18):JSON.parse() 报错场景 
当我们不能确定服务端返回的数据类型时
// 判断数据是否存在var str = str && JSON.parse(str) || {};// 判断数据类型var str = typeof str == "string" ? JSON.parse(str) : {};// 通过 try catch 捕捉异常,防止代码报错var c = null;try {c = JSON.parse(str)} catch (d) {}var g = "";try {g = JSON.stringify(a)} catch (u) {}"object" == typeof a ? JSON.stringify(a) : a
2021.11.9 补充
报错提示 Unexpected token o in JSON at position 1
stackoverflow
可以使用下方进行转换操作
JSON.parse(JSON.stringify(userData))
parse 解析
用来解析JSON 字符串 构造由字符描述的JavaScript值或对象
let arr = '["111","222"]'console.log(JSON.parse(arr)) //["111", "222"]
JSON.stringify()
stringify 字符串化
JSON.stringify({ x: 5 });// '{"x":5}'
every
every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试,返回一个布尔值
注意:若是空数组 返回true
array.every(function(currentValue,index,arr),this.value)
例子
[12, 5, 8, 130, 44].every(x => x >= 10); // falsevar arr = [1,2,3,4]var res = arr.every(function(item){return item < 5})console.log(res) //true注意:every 是测试数组中的每一个值是否满足你所写的函数测试,返回一个布尔值。
场景:全选按钮的实现
data(){return {list:[{id:1,name:'水果',price:12,num:1,checked:false},{id:2,name:'苹果',price:15,num:1,checked:false}],}}// 全选按钮checkAll(){//返回值都是true时 说明商品都是选中状态if(this.list.every(item=>item.checked)){this.list.forEach((item)=>item.checked = false)this.allChecked = false}else{this.list.forEach((item)=>item.checked = true)this.allChecked = true}},
some
some()方法测试数组中是不是至少有一个元素通过了被提供的函数测试,他返回的是一个boolean类型的值
注意:若是空数组 返回false
[2, 5, 8, 1, 4].some(x => x > 10); // false
filter
filter() 方法创建一个新数组,其包含通过所提供函数实现的测试的所有元素
主要是过滤作用 不会改变原数组
补充:原理:如果返回值为true或能转化为true的值,那么传递给判定函数的元素就是这个子集的成员,它将被添加到一个作为返回值的数组中。
var words = ['hello','morning','evening','afternoon','breakfest']var result = words.filter(word => word.length > 6)console.log(result) //["morning", "evening", "afternoon", "breakfest"]
map
map()方法创建一个新数组,其结果是该数组中的每个元素都调用一个函数提供的函数后返回的结果
返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值
注意:map()不会对空数组进行检测
map()不会改变原始数组
语法 : array.map(function(currentValue,index,arr),thisValue)
参数 : 函数 必须 数组中的每个元素都会执行这个函数
currentValue 必须 当前元素的值
index 可选 当前元素的索引值
arr 可选 当前元素属于的数组对象
const arr1 = [1,4,9,16]//x 就是当前元素的值const map1 = arr1.map(x=>x*2)console.log(map1); //Array [2, 8, 18, 32]
object.defineProperty()
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象现有属性,并返回这个对象。
Object.defineProperty(obj, prop, descriptor)obj要在其上定义属性的对象prop要定义或修改的属性的名称descriptor将被定义或修改的属性描述符
instanceof
检测构造函数的prototype属性是否出现在某个实例对象的原型链上
function C(){}console.log(C instanceof Object) //true
parseInt
语法: parseInt (string,radix)
radix 表示要解析的数字的基数,2-36之间。如果省略该参数或其值为0 ,则数字将以10为基数来解析、如果它以 “0x” 或 “0X” 开头,将以 16 为基数。如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。
可解析一个字符串,并返回一个整数
parseInt("10"); //返回 10parseInt("19",10); //返回 19 (10+9)parseInt("11",2); //返回 3 (2+1)parseInt("17",8); //返回 15 (8+7)parseInt("1f",16); //返回 31 (16+15)parseInt("010"); //未定:返回 10 或 8
parseInt(string, radix)
可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。
如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。
算这个进制的方法
如果parseInt的字符不是指定基数中的数字(基数大于 10 时,用字母表中的字母来表示大于9 的数字。例如十六进制中,使用 A到 F。),则忽略该字符和所有后续字符,并返回解析到该点的整数值。parseInt将数字截断为整数值。允许使用前导空格和尾随空格。
意思就是比如 15 那么就看成1
除了“0、1”外,其它数字都不是有效二进制数字
parseInt('123', 5) // 将'123'看作5进制数,返回十进制数38 => 1*5^2 + 2*5^1 + 3*5^0 = 38计算过程因为固定是返回十进制数,所以只需要记住方法就可以3*5^0 + 2*5^1 + 1*5^2 = 38
charCodeAt
charCodeAt() 方法可返回指定位置的字符的 Unicode 编码
语法 : string.charCodeAt(index)
若大于255即为中文字符
while
while语句可以在某个条件表达为真的前提下,循环执行制定的一段代码,直到那个表达式不为真时结束循环
let n = 0while(n<3){n++}console.log(n) //3另一种使用方法使用场景:根据这个值执行多少次数var n = 5while(n--){console.log(n) //4 3 2 1 0}
setInterval
setInterval()会一直调用函数,关闭它需要将这个 定时器 的id 传给 clearInterval() 方法
场景: 验证码倒计时
<span v-if="count == 0" @click="sendCode">发送验证码</span><span v-else>已发送{{count}}s</span>data() {return {count:0};},sendCode(){this.count = 60this.timeIntervalId = setInterval(() => {this.count --if(this.count == 0){clearInterval(this.timeIntervalId)}}, 1000);}
find
返回数组中满足条件的第一个元素的值。否则返回 undefined
const names = ["Kai", "Katharina", "Tim"];const shortName = names.find(name=>name.length < 4)console.log(shortName) //Kai
<script>const characters = [{id: 1,name: 'ironman',env: 'marvel'},{id: 2,name: 'black_widow',env: 'aaa'},{id: 3,name: 'wonder_woman',env: 'dc_comics'},];function hasFrom(env) {return character => character.env === env}console.log(characters.find(hasFrom('marvel'))) //返回数组中的第一个满足条件的值 这里返回的是数组的第一个对象</script>
findIndex()
满足数组中满足提供的条件的第一个元素的索引,否则返回-1
<script>const characters = [{id: 1,name: 'ironman',env: 'marvel'},{id: 2,name: 'black_widow',env: 'aaa'},{id: 3,name: 'wonder_woman',env: 'dc_comics'},];function hasFrom(env) {return character => character.env === env}console.log(characters.findIndex(hasFrom('marvel'))) //0</script>
逻辑运算符 &&

通常情况下: 返回一个布尔值
&& 和 || 会返回一个指定操作数的值,可用于非布尔值
const a = 3const b = -2console.log(a>0&&b>0) //falseconsole.log(a>0||b>0) //trueconsole.log(!(a > 0 || b > 0)) //false
function getValue() {console.log("执行了")}const a = 3const b = -2a > 0 && getValue() //执行了
会被转换为false的表达式
- 空字符串
- null
- NaN
- undefined
- 0
短路计算
因为逻辑运算是从左到右边。分为两种情况.右边的代码不会被执行
( false )&& (expr) false
( true )|| (expr) true
删除嵌套的小括号
and
bCondition1 || (bCondition2 && bCondition3)等价于bCondition1 || bCondition2 && bCondition3
splice
返回值 由被删除的元素组成的一个数组
array.splice(start[, deleteCount[, item1[, item2[, ...]]]])deleteCount 可选当为0时候,或者是负数,则不移除元素。这种情况下,至少会添加一个元素。
const months = ['Jan', 'March', 'April', 'June'];months.splice(4,2,'six')console.log(months) //["Jan", "March", "April", "June", "six"]从第四项开始 删除后面的一个元素,在添加元素进来const months = ['Jan', 'March', 'April', 'June','5','6'];months.splice(4,1,'six')console.log(months) //["Jan", "March", "April", "June", "six", "6"]
Array.from
https://segmentfault.com/a/1190000004450221
ArrayLike 指的是对象具有数组某些行为的对象,有length属性,看下面
var obj = {"0":1,length:1}obj.map //undefined
问题:这一类对象不能调用数组的方法(push/forEach/map),常见的有两种,DOM中的NodeList和函数中的arguments。
平常开发中:
var args = [].slice.call(arguments);var imgs = [].slice.call(document.querySelectorAll('img'));
Array.from 写法
var args = Array.from(arguments);var imgs = Array.from(document.querySelectorAll('img'));
注意:类数组对象中必须是需要有length 属性的,不然转换为数组的时候是空
Set
Set对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。set中的元素只会出现一次
Array 相关
let myArray = ["value1", "value2", "value3"];// 用Set构造器将Array转换为Setlet mySet = new Set(myArray);mySet.has("value1"); // returns true// 用...(展开操作符)操作符将Set转换为Arrayconsole.log([...mySet]); // 与myArray完全一致
数组去重
const numbers = [2,3,4,4,2,3,3,4,4,5,5,6,6,7,5,32,3,4,5]console.log([...new Set(numbers)])// [2, 3, 4, 5, 6, 7, 32]
instanceof
检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
function C(){}function D(){}var o = new C()console.log(o instanceof C) //true Object.getPrototypeOf(o) === C.prototype
sort
arr.sort([compareFunction])
默认按照 Unicode 位点排序 (字典序即 默认规则就是按照字母顺序)
返回值:排序后的数组,原地排序,并且不进行复制
function compare(a,b){return a - b}
对象可以按照某个属性排序
var items = [{name: 'Edward',value: 21},{name: 'Sharpe',value: 37},{name: 'And',value: 45},{name: 'The',value: -12},{name: 'Magnetic',value:1111},{name: 'Zeros',value: 37}];var newArr = items.sort(function(a,b){return (a.value - b.value)})console.log(newArr)疑问:如果某个属性的值没有的话,该如何进行比较
switch case
语法格式
switch(expression){case value ://语句break; //可选case value ://语句break; //可选//你可以有任意数量的case语句default : //可选//语句}
switch(i){case 25:console.log("25")break;case 35:console.log("35")break;default:console.log('other')}
区别:与 else if 的区别
- switch … case… 会占用较多的代码空间,因为要生成跳表。
- 当分支较多的时候,使用switch效率更高,if … else 是遍历所有的值找到符合条件的分支。
Object.create()
**Object.create()**方法创建一个新对象,使用现有的对象来提供新创建的对象的proto。
有时候拿不到构造函数,只能拿到一个现有的对象,希望以这个现有的对象作为模板,生成新的实例对象。
var person1 = {name: "chu",age: 20,greeting: function () {console.log(this.name)}}var person2 = Object.create(person1)console.log(person2.name) //chu
concat
var new_array = old_array.concat(value1[, value2[, …[, valueN]]]) value 可选 注:如果省略了所有的valueN参数 则concat会返回调用此方法的现存数组的一个浅拷贝
用于合并两个或多个数组,此方法不会更改现有数组,而是返回一个新数组
const array1 = ["1", "2", "3"]const array2 = ["4", "5"]const array3 = array1.concat(array2)console.log(array3) // ["1", "2", "3", "4", "5"]
稀松数组
定义:稀松数组并不含有从0开始的连续索引,一般length属性值比实际元素个数大。
遍历稀松数组时用in操作符或者判断是否为undefined
面试题
arr[3] = 1 打印 arr.length = 4 稀松数组
var arr = new Array(4)arr[3] = 1
addEventListener 函数
element.addEventListener(event, function, useCapture)
第三个参数涉及冒泡和捕获. true时为捕获,false为冒泡
Object.keys
遍历对象的方法。会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 。
let obj = {1: 2, 2: 2, a: 6, s: 8, b: 2}Object.keys(obj)["1", "2", "a", "s", "b"]
2021.9.6 补充:关于自身可枚举的属性
let animal = {eats: true};let rabbit = {jumps: true,__proto__: animal};// Object.keys 只返回自己的 keyalert(Object.keys(rabbit)); // jumps
hasOwnProperty
**hasOwnProperty()** 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)
下面的例子演示了如何在遍历一个对象的所有属性时忽略掉继承属性.
var buz = {fog: 'stack'};for (var name in buz) {if (buz.hasOwnProperty(name)) {console.log('this is fog (' +name + ') for sure. Value: ' + buz[name]);}else {console.log(name); // toString or something else}}
Map.set()
set() 方法为 Map 对象添加或更新了一个指定键(key)和值(value)的(新)键值对
const map1 = new Map();map1.set('bar', 'foo');console.log(map1.get('bar'));// expected output: "foo"console.log(map1.get('baz'));// expected output: undefined
补充说明:
Map 中可以存 ‘2,3’ 这样的键,举例说明
let cache = new Map()cache.set('2,3',15)console.log(cache) //Map(1) { '2,3' => 15 }console.log(cache.get('2,3')) //15
案例来源
https://zh.javascript.info/call-apply-decorators
flat
flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。var newArray = arr.flat([depth])
depth 可选
默认深度为 1
const arr1 = [0, 1, 2, [3, 4]];console.log(arr1.flat());// expected output: [0, 1, 2, 3, 4]const arr2 = [0, 1, 2, [[[3, 4]]]];console.log(arr2.flat(2));// expected output: [0, 1, 2, [3, 4]]//使用 Infinity,可展开任意深度的嵌套数组var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];arr4.flat(Infinity);// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
替代方案
使用 reduce 和 concat
var arr = [1, 2, [3, 4]];// 展开一层数组arr.flat();// 等效于arr.reduce((acc, val) => acc.concat(val), []);// [1, 2, 3, 4]// 使用扩展运算符 ...const flattened = arr => [].concat(...arr);
