2011-12-01 57 views
1

我正在为Array接收一个函数,然后为Array中的每个项目调用它的数组写入扩展方法。Array上的JavaScript扩展

它工作正常,除了扩展本身被添加到函数调用后的数组。所以在警报部分,第三个警报在字符串中显示了我的foo函数。

下面的代码:

Array.prototype.foo = function (F) { 
    for (var i in this) { 
     this[i] = F(this[i]); 
    } 
} 

var items = ["a", "b"]; 

items.foo(function (data) { 
    return data + 1; 
}); 

for (var i in items) { 
    alert(items[i]); // expected to see a1 and b1 but also displayed foo as string. 
} 
+0

不要在''中使用''''''。 – SLaks

+0

迭代数组内容,而不是其属性。 –

+0

只是一个样式问题,但我不会使用大写'F'作为函数变量的名称,请使用'fn'。 – jabclab

回答

4

这是因为for in正在经历按键阵列,而不是元素。你要切换你的循环(我相信):

for (var e = 0; e < this.length; e++){ 
    // call against this[e] now 
} 

例如:

var ary = ['a','b','c'] 
for (var a = 0; a < ary.length; a++){ 
    console.log(ary[a]); // echos a, b, c 
} 

var obj = {a:'X',b:'Y',c:'Z'} 
for (var a in obj){ 
    console.log(a);  // echos a, b, c 
    console.log(obj[a]) // echos X, Y, Z 
} 
0

即从预期“的为(以项目VAR)”,因为它通过枚举对象字段,而不是索引。

0

如果您打算循环播放对象字段,则可以在分配前添加typeof(this[i]) != 'function'检查。

2

I + 1了布拉德·克里斯蒂的答案,但我想补充一点,这是可能的,开始在JavaScript 1.8.5,创建不for(var ... in ...)报表显示,通过使用the defineProperty method属性。这将是这样的:

Object.defineProperty 
(
    Array.prototype, 
    'foo', 
    { 
    value: 
     function (f) 
     { 
     for (var i = 0; i < this.length; ++i) 
      this[i] = f(this[i]); 
     } 
    } 
); 

var items = [1, 2, 3]; 
items.foo(function (n) { return 2 * n; }); // now items = [2, 4, 6] 
for (var i in items) 
    alert(items[i]); // alerts 2, then 4, then 6 

也就是说,JavaScript的1.8.5仅2010年就出来了,所以它可能不是一个好主意,但是,写依赖于它的代码。

+0

优秀点。 –