2011-12-01 62 views
4

在使用我最新的Web应用程序并需要使用Array.forEach函数时,我经常发现以下代码用于添加对没有内置函数的旧浏览器的支持。Array.prototype.forEach替代实现参数

/** 
* Copyright (c) Mozilla Foundation http://www.mozilla.org/ 
* This code is available under the terms of the MIT License 
*/ 
if (!Array.prototype.forEach) { 
    Array.prototype.forEach = function(fun /*, thisp*/) { 
     var len = this.length >>> 0; 
     if (typeof fun != "function") { 
      throw new TypeError(); 
     } 

     var thisp = arguments[1]; 
     for (var i = 0; i < len; i++) { 
      if (i in this) { 
       fun.call(thisp, this[i], i, this); 
      } 
     } 
    }; 
} 

我完全理解代码的作用和它是如何工作的,但我总能看到它与正式thisp参数复制注释出来,并有它被设置为使用arguments[1]而不是局部变量。

我想知道是否有人知道为什么会做出这样的改变,因为从我所知道的情况来看,代码在thisp中作为一个形式参数而不是变量可以正常工作吗?

回答

5

Array.prototype.forEach.length被定义为1,所以执行的功能会更类似天然的,如果他们有他们的.length属性设置为1了。

http://es5.github.com/#x15.4.4.18

在foreach方法的长度属性是1

func.lengthfunc需要根据它的定义自变量的量。)

对于func.length到是1,你必须定义func只需要1个参数。在函数本身中,您始终可以使用arguments获取所有参数。但是,通过将函数定义为1参数,.length属性为1。因此,根据规范更为正确。

+0

嗯,有道理。我想知道为什么长度是1.我想这是因为第二个参数是可选的? (我从来不知道函数的长度是参数的数量,整洁!) – Joshua

+0

@Joshua:很可能,但无论规范说什么,它是如何定义的,即使没有明确的理由:) – pimvdb

-1

这将迭代数组中的每个值而不迭代原型函数的字符串等效项。

Array.prototype.forEach = function(fun /*, thisp*/) { 
    if (typeof fun != "function") { 
     throw new TypeError(); 
    } 

    for(i = 0; i < this.length; i++){ 
     ... 
    } 

}