forEach

  • 版本网址缩略名: JavaScript/Reference/Global_Objects/Array/forEach
  • 版本标题: forEach
  • 版本 id: 484513
  • 创建于:
  • 创建者: yanhaijing1234
  • 是否是当前版本?
  • 评论

修订内容

概述

为每个数组元素执行一次指定的函数.

Method of Array
Implemented in JavaScript 1.6
ECMAScript Edition ECMAScript 5th Edition

语法

array.forEach(callback[, thisArg])

参数

callback
为每个数组元素执行的函数.
thisArg
在执行callback函数时指定的this值.

描述

forEach 方法为数组中的每个有值的元素执行一次给定的callback函数,只有在那些有值的索引上才会调用callback函数,那些被删除掉的索引或者从未赋值过的索引将会被跳过.

callback函数会被依次传入三个参数:

  • 元素值
  • 元素索引
  • 被遍历的数组对象本身

如果 thisArg参数被提供,它将作为callback函数的执行上下文,类似执行如下函数callback.call(thisArg, element, index, array)。如果thisArg是 undefined 或 null,函数的 this 值取决于函数是否在严格模式(严格模式下为空,非严格模式下为全局对象)。

The range of elements processed by forEach is set before the first invocation of callback. Elements which are appended to the array after the call to forEach begins will not be visited by callback. If existing elements of the array are changed, or deleted, their value as passed to callback will be the value at the time forEach visits them; elements that are deleted are not visited.

示例

打印出数组的内容

下面的代码会为每一个数组元素输出一行记录:

function logArrayElements(element, index, array) {
    console.log("a[" + index + "] = " + element);
}
[2, 5, 9].forEach(logArrayElements);
// logs:
// a[0] = 2
// a[1] = 5
// a[2] = 9

一个可以克隆对象的函数

使用下面的代码可以复制一个给定的对象,虽然有很多不同的复制对象的方法.不过下面介绍的这种方法使用了Array.prototype.forEach和其他一些ECMAScript 5中的Object.*函数.

function copy(o){
  var copy = Object.create( Object.getPrototypeOf(o) );
  var propNames = Object.getOwnPropertyNames(o);

  propNames.forEach(function(name){
    var desc = Object.getOwnPropertyDescriptor(o, name);
    Object.defineProperty(copy, name, desc);
  });

  return copy;
}

var o1 = {a:1, b:2};
var o2 = copy(o1); // o2 looks like o1 now

在旧环境上使用JavaScript实现该方法

forEach 是在最近被添加到 ECMA-262 标准的;这样它可能在标准的其他实现中不存在,你可以在你调用 forEach 之前 插入下面的代码,在本地不支持的情况下使用forEach。

if ( !Array.prototype.forEach ) {
  Array.prototype.forEach = function(fn, scope) {
    for(var i = 0, len = this.length; i < len; ++i) {
      fn.call(scope, this[i], i, this);
    }
  }
}

An algorithm 100% true to the ECMA-262, 5th edition can be seen below:

This algorithm is exactly the one specified in ECMA-262, 5th edition, assuming Object and TypeError have their original values and that callback.call evaluates to the original value of Function.prototype.call.

// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.com/#x15.4.4.18
if ( !Array.prototype.forEach ) {

  Array.prototype.forEach = function forEach( callback, thisArg ) {

    var T, k;

    if ( this == null ) {
      throw new TypeError( "this is null or not defined" );
    }

    // 1. Let O be the result of calling ToObject passing the |this| value as the argument.
    var O = Object(this);

    // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
    // 3. Let len be ToUint32(lenValue).
    var len = O.length >>> 0; // Hack to convert O.length to a UInt32

    // 4. If IsCallable(callback) is false, throw a TypeError exception.
    // See: http://es5.github.com/#x9.11
    if ( {}.toString.call(callback) !== "[object Function]" ) {
      throw new TypeError( callback + " is not a function" );
    }

    // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
    if ( thisArg ) {
      T = thisArg;
    }

    // 6. Let k be 0
    k = 0;

    // 7. Repeat, while k < len
    while( k < len ) {

      var kValue;

      // a. Let Pk be ToString(k).
      //   This is implicit for LHS operands of the in operator
      // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
      //   This step can be combined with c
      // c. If kPresent is true, then
      if ( Object.prototype.hasOwnProperty.call(O, k) ) {

        // i. Let kValue be the result of calling the Get internal method of O with argument Pk.
        kValue = O[ k ];

        // ii. Call the Call internal method of callback with T as the this value and
        // argument list containing kValue, k, and O.
        callback.call( T, kValue, k, O );
      }
      // d. Increase k by 1.
      k++;
    }
    // 8. return undefined
  };
}

浏览器兼容性

{{ CompatibilityTable() }}

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support {{ CompatVersionUnknown() }} 1.5 9 {{ CompatVersionUnknown() }} {{ CompatVersionUnknown() }}
Feature Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support {{ CompatUnknown() }} {{ CompatUnknown() }} {{ CompatUnknown() }} {{ CompatUnknown() }} {{ CompatUnknown() }}

相关链接

Array.map

修订版来源

<h2 id=".E6.A6.82.E8.BF.B0">概述</h2>
<p>为每个数组元素执行一次指定的函数.</p>
<table class="standard-table">
 <thead>
  <tr>
   <th class="header" colspan="2">Method of <a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/Array" title="JavaScript/Reference/Global_Objects/Array"><code>Array</code></a></th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>Implemented in</td>
   <td>JavaScript 1.6</td>
  </tr>
  <tr>
   <td>ECMAScript Edition</td>
   <td>ECMAScript 5th Edition</td>
  </tr>
 </tbody>
</table>
<h2 id=".E8.AF.AD.E6.B3.95">语法</h2>
<pre class="syntaxbox">
<code><em>array</em>.forEach(<em>callback</em>[, <em>thisArg</em>])</code></pre>
<h3 id=".E5.8F.82.E6.95.B0">参数</h3>
<dl>
 <dt>
  <code>callback</code></dt>
 <dd>
  为每个数组元素执行的函数.</dd>
 <dt>
  <code>thisArg</code></dt>
 <dd>
  在执行<code>callback</code>函数时指定的<code>this值</code>.</dd>
</dl>
<h2 id=".E6.8F.8F.E8.BF.B0">描述</h2>
<p><code>forEach</code> 方法为数组中的每个有值的元素执行一次给定的<code>callback</code>函数,只有在那些有值的索引上才会调用<code>callback</code>函数,那些被删除掉的索引或者从未赋值过的索引将会被跳过.</p>
<p><code>callback函数会被依次传入三个参数</code>:</p>
<ul>
 <li><strong>元素值</strong></li>
 <li><strong>元素索引</strong></li>
 <li><strong>被遍历的数组对象本身</strong></li>
</ul>
<p>如果 thisArg参数被提供,它将作为callback函数的执行上下文,类似执行如下函数<span style="font-family: 'Courier New', 'Andale Mono', monospace; line-height: inherit;">callback.call(thisArg, element, index, array)。如果thisArg是 undefined 或 null,函数的 this 值取决于函数是否在严格模式(严格模式下为空,非严格模式下为全局对象)。</span></p>
<p>The range of elements processed by <code>forEach</code> is set before the first invocation of <code>callback</code>. Elements which are appended to the array after the call to <code>forEach</code> begins will not be visited by <code>callback</code>. If existing elements of the array are changed, or deleted, their value as passed to <code>callback</code> will be the value at the time <code>forEach</code> visits them; elements that are deleted are not visited.</p>
<h2 id=".E7.A4.BA.E4.BE.8B">示例</h2>
<h3 id=".E6.89.93.E5.8D.B0.E5.87.BA.E6.95.B0.E7.BB.84.E7.9A.84.E5.86.85.E5.AE.B9">打印出数组的内容</h3>
<p>下面的代码会为每一个数组元素输出一行记录:</p>
<pre class="brush:js">
function logArrayElements(element, index, array) {
    console.log("a[" + index + "] = " + element);
}
[2, 5, 9].forEach(logArrayElements);
// logs:
// a[0] = 2
// a[1] = 5
// a[2] = 9
</pre>
<h3 id=".E4.B8.80.E4.B8.AA.E5.8F.AF.E4.BB.A5.E5.85.8B.E9.9A.86.E5.AF.B9.E8.B1.A1.E7.9A.84.E5.87.BD.E6.95.B0">一个可以克隆对象的函数</h3>
<p>使用下面的代码可以复制一个给定的对象,虽然有很多不同的复制对象的方法.不过下面介绍的这种方法使用了<code>Array.prototype.forEach</code>和其他一些ECMAScript 5中的Object.*函数.</p>
<pre class="brush: js">
function copy(o){
  var copy = Object.create( Object.getPrototypeOf(o) );
  var propNames = Object.getOwnPropertyNames(o);

  propNames.forEach(function(name){
    var desc = Object.getOwnPropertyDescriptor(o, name);
    Object.defineProperty(copy, name, desc);
  });

  return copy;
}

var o1 = {a:1, b:2};
var o2 = copy(o1); // o2 looks like o1 now
</pre>
<h2 id=".E5.9C.A8.E6.97.A7.E7.8E.AF.E5.A2.83.E4.B8.8A.E4.BD.BF.E7.94.A8JavaScript.E5.AE.9E.E7.8E.B0.E8.AF.A5.E6.96.B9.E6.B3.95">在旧环境上使用JavaScript实现该方法</h2>
<p><code>forEach</code>&nbsp;是在最近被添加到 ECMA-262 标准的;这样它可能在标准的其他实现中不存在,你可以在你调用 forEach 之前 插入下面的代码,在本地不支持的情况下使用forEach。</p>
<pre class="brush:js">
if ( !Array.prototype.forEach ) {
  Array.prototype.forEach = function(fn, scope) {
    for(var i = 0, len = this.length; i &lt; len; ++i) {
      fn.call(scope, this[i], i, this);
    }
  }
}
</pre>
<p>An algorithm 100% true to the ECMA-262, 5th edition can be seen below:</p>
<p>This algorithm is exactly the one specified in ECMA-262, 5th edition, assuming <code>Object</code> and <code>TypeError</code> have their original values and that <code>callback.call</code> evaluates to the original value of <code><a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/Function/call" title="JavaScript/Reference/Global Objects/Function/call">Function.prototype.call</a></code>.</p>
<!-- DO_NOT_MODIFY_THE_FOLLOWING_CODE_IN_ANY_WAY -->
<pre class="brush: js">
// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.com/#x15.4.4.18
if ( !Array.prototype.forEach ) {

  Array.prototype.forEach = function forEach( callback, thisArg ) {

    var T, k;

    if ( this == null ) {
      throw new TypeError( "this is null or not defined" );
    }

    // 1. Let O be the result of calling ToObject passing the |this| value as the argument.
    var O = Object(this);

    // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
    // 3. Let len be ToUint32(lenValue).
    var len = O.length &gt;&gt;&gt; 0; // Hack to convert O.length to a UInt32

    // 4. If IsCallable(callback) is false, throw a TypeError exception.
    // See: http://es5.github.com/#x9.11
    if ( {}.toString.call(callback) !== "[object Function]" ) {
      throw new TypeError( callback + " is not a function" );
    }

    // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
    if ( thisArg ) {
      T = thisArg;
    }

    // 6. Let k be 0
    k = 0;

    // 7. Repeat, while k &lt; len
    while( k &lt; len ) {

      var kValue;

      // a. Let Pk be ToString(k).
      //   This is implicit for LHS operands of the in operator
      // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
      //   This step can be combined with c
      // c. If kPresent is true, then
      if ( Object.prototype.hasOwnProperty.call(O, k) ) {

        // i. Let kValue be the result of calling the Get internal method of O with argument Pk.
        kValue = O[ k ];

        // ii. Call the Call internal method of callback with T as the this value and
        // argument list containing kValue, k, and O.
        callback.call( T, kValue, k, O );
      }
      // d. Increase k by 1.
      k++;
    }
    // 8. return undefined
  };
}
</pre>
<h2 id=".E6.B5.8F.E8.A7.88.E5.99.A8.E5.85.BC.E5.AE.B9.E6.80.A7">浏览器兼容性</h2>
<p>{{ CompatibilityTable() }}</p>
<div id="compat-desktop">
 <table class="compat-table">
  <tbody>
   <tr>
    <th>Feature</th>
    <th>Chrome</th>
    <th>Firefox (Gecko)</th>
    <th>Internet Explorer</th>
    <th>Opera</th>
    <th>Safari</th>
   </tr>
   <tr>
    <td>Basic support</td>
    <td>{{ CompatVersionUnknown() }}</td>
    <td>1.5</td>
    <td>9</td>
    <td>{{ CompatVersionUnknown() }}</td>
    <td>{{ CompatVersionUnknown() }}</td>
   </tr>
  </tbody>
 </table>
</div>
<div id="compat-mobile">
 <table class="compat-table">
  <tbody>
   <tr>
    <th>Feature</th>
    <th>Android</th>
    <th>Firefox Mobile (Gecko)</th>
    <th>IE Mobile</th>
    <th>Opera Mobile</th>
    <th>Safari Mobile</th>
   </tr>
   <tr>
    <td>Basic support</td>
    <td>{{ CompatUnknown() }}</td>
    <td>{{ CompatUnknown() }}</td>
    <td>{{ CompatUnknown() }}</td>
    <td>{{ CompatUnknown() }}</td>
    <td>{{ CompatUnknown() }}</td>
   </tr>
  </tbody>
 </table>
</div>
<h2 id=".E7.9B.B8.E5.85.B3.E9.93.BE.E6.8E.A5">相关链接</h2>
<p><a class="internal" href="https://developer.mozilla.org/zh-CN/docs/JavaScript/Reference/Global_Objects/Array/map">Array.map</a></p>
恢复到这个版本