---
title: Array.prototype.flat()
slug: Web/JavaScript/Reference/Global_Objects/Array/flat
tags:
  - JavaScript
  - 原型
  - 参考
  - 数组
  - 方法
translation_of: Web/JavaScript/Reference/Global_Objects/Array/flat
---
<div>{{JSRef}}</div>

<p><code><strong>flat()</strong></code> 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。</p>

<div>{{EmbedInteractiveExample("pages/js/array-flat.html")}}</div>



<h2 id="语法">语法</h2>

<pre class="syntaxbox notranslate"><var>var newArray = arr</var>.flat([<var>depth]</var>)</pre>

<h3 id="参数">参数</h3>

<dl>
 <dt><code>depth</code> {{optional_inline}}</dt>
 <dd>指定要提取嵌套数组的结构深度,默认值为 1。</dd>
</dl>

<h3 id="返回值">返回值</h3>

<p>一个包含将数组与子数组中所有元素的新数组。</p>

<h2 id="示例">示例</h2>

<h3 id="扁平化嵌套数组">扁平化嵌套数组</h3>

<pre class="notranslate">var arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]

var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]

var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]

//使用 Infinity,可展开任意深度的嵌套数组
<code>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]</code></pre>

<h3 id="扁平化与数组空项">扁平化与数组空项</h3>

<p><code>flat()</code> 方法会移除数组中的空项:</p>

<pre class="brush: js notranslate">var arr4 = [1, 2, , 4, 5];
arr4.flat();
// [1, 2, 4, 5]</pre>

<h2 id="替代方案">替代方案</h2>

<h3 id="使用_reduce_与_concat">使用 <code>reduce</code> 与 <code>concat</code></h3>

<pre class="notranslate"><code>var arr = [1, 2, [3, 4]];

// 展开一层数组
arr.flat();
// 等效于
arr.reduce((acc, val) =&gt; acc.concat(val), []);
// [1, 2, 3, 4]

// 使用扩展运算符 ...
const flattened = arr =&gt; [].concat(...arr);</code></pre>

<h3 class="brush: js" id="reduce_concat_isArray_recursivity">reduce + concat + isArray + recursivity</h3>

<pre class="brush: js notranslate"><code>// 使用 reduce、concat 和递归展开无限多层嵌套的数组
var arr1 = [1,2,3,[1,2,3,4, [2,3,4]]];
</code>
<code class="language-js"><span class="keyword token">function</span> <span class="function token">flatDeep</span><span class="punctuation token">(</span><span class="parameter token">arr<span class="punctuation token">,</span> d <span class="operator token">=</span> <span class="number token">1</span></span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
   <span class="keyword token">return</span> d <span class="operator token">&gt;</span> <span class="number token">0</span> <span class="operator token">?</span> arr<span class="punctuation token">.</span><span class="function token">reduce</span><span class="punctuation token">(</span><span class="punctuation token">(</span><span class="parameter token">acc<span class="punctuation token">,</span> val</span><span class="punctuation token">)</span> <span class="operator token">=&gt;</span> acc<span class="punctuation token">.</span><span class="function token">concat</span><span class="punctuation token">(</span>Array<span class="punctuation token">.</span><span class="function token">isArray</span><span class="punctuation token">(</span>val<span class="punctuation token">)</span> <span class="operator token">?</span> <span class="function token">flatDeep</span><span class="punctuation token">(</span>val<span class="punctuation token">,</span> d <span class="operator token">-</span> <span class="number token">1</span><span class="punctuation token">)</span> <span class="punctuation token">:</span> val<span class="punctuation token">)</span><span class="punctuation token">,</span> <span class="punctuation token">[</span><span class="punctuation token">]</span><span class="punctuation token">)</span>
                <span class="punctuation token">:</span> arr<span class="punctuation token">.</span><span class="function token">slice</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span><span class="punctuation token">;</span></code>
<code>
flatDeep(arr1, Infinity);
// [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]</code></pre>

<h3 id="forEachisArraypushrecursivity">forEach+isArray+push+recursivity</h3>

<pre class="brush: js notranslate">// forEach 遍历数组会自动跳过空元素
const eachFlat = (arr = [], depth = 1) =&gt; {
  const result = []; // 缓存递归结果
  // 开始递归
  (function flat(arr, depth) {
    // forEach 会自动去除数组空位
    arr.forEach((item) =&gt; {
      // 控制递归深度
      if (Array.isArray(item) &amp;&amp; depth &gt; 0) {
        // 递归数组
        flat(item, depth - 1)
      } else {
        // 缓存元素
        result.push(item)
      }
    })
  })(arr, depth)
  // 返回递归结果
  return result;
}

// for of 循环不能去除数组空位,需要手动去除
const forFlat = (arr = [], depth = 1) =&gt; {
  const result = [];
  (function flat(arr, depth) {
    for (let item of arr) {
      if (Array.isArray(item) &amp;&amp; depth &gt; 0) {
        flat(item, depth - 1)
      } else {
        // 去除空元素,添加非undefined元素
        item !== void 0 &amp;&amp; result.push(item);
      }
    }
  })(arr, depth)
  return result;
}
</pre>

<h3 id="使用堆栈stack">使用堆栈stack</h3>

<pre class="notranslate">// 无递归数组扁平化,使用堆栈
// 注意:深度的控制比较低效,因为需要检查每一个值的深度
// 也可能在 shift / unshift 上进行 w/o 反转,但是末端的数组 OPs 更快
var arr1 = [1,2,3,[1,2,3,4, [2,3,4]]];
function flatten(input) {
  const stack = [...input];
  const res = [];
  while (stack.length) {
    // 使用 pop 从 stack 中取出并移除值
    const next = stack.pop();
    if (Array.isArray(next)) {
      // 使用 push 送回内层数组中的元素,不会改动原始输入
      stack.push(...next);
    } else {
      res.push(next);
    }
  }
  // 反转恢复原数组的顺序
  return res.reverse();
}
flatten(arr1);// [1, 2, 3, 1, 2, 3, 4, 2, 3, 4]</pre>

<pre class="notranslate">// 递归版本的反嵌套
function flatten(array) {
  var flattend = [];
  (function flat(array) {
    array.forEach(function(el) {
      if (Array.isArray(el)) flat(el);
      else flattend.push(el);
    });
  })(array);
  return flattend;
}</pre>

<h3 id="Use_Generator_function">Use <code>Generator</code> function</h3>

<pre class="notranslate"><code>function* flatten(array) {
    for (const item of array) {
        if (Array.isArray(item)) {
            yield* flatten(item);
        } else {
            yield item;
        }
    }
}

var arr = [1, 2, [3, 4, [5, 6]]];
const flattened = [...flatten(arr)];
// [1, 2, 3, 4, 5, 6]</code></pre>

<p>Please do not add polyfills on this article. For reference, please check: <a href="https://discourse.mozilla.org/t/mdn-rfc-001-mdn-wiki-pages-shouldnt-be-a-distributor-of-polyfills/24500">https://discourse.mozilla.org/t/mdn-rfc-001-mdn-wiki-pages-shouldnt-be-a-distributor-of-polyfills/24500</a></p>

<h2 id="Specifications">Specifications</h2>

<table>
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td><a href="https://www.ecma-international.org/ecma-262/10.0/index.html#sec-array.prototype.flat">ECMAScript 2019</a></td>
   <td>Finished</td>
   <td>Initial definition</td>
  </tr>
 </tbody>
</table>

<h2 id="浏览器兼容性">浏览器兼容性</h2>

<div>


<p>{{Compat("javascript.builtins.Array.flat")}}</p>
</div>

<h2 id="参见">参见</h2>

<ul>
 <li>{{jsxref("Array.prototype.flatMap()")}}</li>
 <li>{{jsxref("Array.prototype.map()")}}</li>
 <li>{{jsxref("Array.prototype.reduce()")}}</li>
 <li>{{jsxref("Array.prototype.concat()")}}</li>
</ul>