2010-11-12 64 views
3

在Python中,你可以像这样:Javascript地图本地对象的方法

>>> list(map(str.upper, ['foo','bar'])) 
['FOO', 'BAR'] 

我希望能够做同样的事情在javascript:

我已经尝试使用下面的Chrome浏览器原生地图实现(https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map):

['foo','bar'].map(String.prototype.toUpperCase) 

['foo','bar'].map(String.prototype.toUpperCase.call) 

为什么不调用工作? 有没有任何优雅的方式来做到这一点,或者我必须在回调函数中包装toUpperCase? THX

+0

'toUpperCase.call'不起作用,因为'call'是针对'Function.prototype'解析的,因此与'toUpperCase'无关。它看着'this'来确定哪个方法被调用,'map'调用函数的方式,'this'是'undefined'。 – 2010-11-12 18:39:14

回答

1

现代浏览器都支持这个(although it is a recent addition

var a = ['foo','bar']; 
var b = a.map(String.toUpperCase); 

alert(b[1]); 

甚至

var a = ['foo','bar'].map(String.toUpperCase); 
alert(a[0]); 

例如:http://www.jsfiddle.net/xPsba/

+0

这可以在firefox 4中使用,但不能在mac上使用chrome 7。猜猜我必须把它包装在一个函数:) – Baversjo 2010-11-12 18:42:26

+1

这不会在Firefox以外的其他浏览器上工作,因为'String.toUpperCase'是* Mozilla扩展名*,不是ECMAScript标准的一部分(注意可能是错误的与'String.prototype.toUpperCase'相混淆),他们将这些“静态”方法称为“数组和字符串泛型”,我并不认为其他的实现者会将它们包含在内...... – CMS 2010-11-12 19:00:49

+0

@CMS,它适用于FF,IE ,Chrome,Safari和Opera for windows .. – 2010-11-12 19:18:56

-1

您可以使用这样的事情:

function map(arr, fn){ 
    var i = 0, len = arr.length, ret = []; 
    while(i < len){ 
     ret[i] = fn(arr[i++]); 
    } 
    return ret; 
} 

,并使用它:

var result = map(['foo', 'bar'], function(item) { 
    return item.toUpperCase(); 
}); 

console.log (result); // => ['FOO', 'BAR'] 
+0

您有任何示例用法吗?我宁愿使用本地地图功能。 – Baversjo 2010-11-12 18:35:28

+0

它还没有广泛的可用 – Mic 2010-11-12 18:39:50

+0

for循环会更简单很多:p – 2010-11-12 21:53:12

1

这是因为String.prototype.toUpperCasethis(上下文)的对象,但map功能运行不能设置数组元素作为上下文。它通过它作为一个参数。一种解决方法是

['foo','bar'].map(function(k) { return String.prototype.toUpperCase.call(k) }); 
+0

更好的办法是完全跳过原型部分,并将其用作'['foo','bar'] .map(String.toUpperCase);'它在正确的上下文中运行。 – 2010-11-12 18:40:50

1

尝试:

['foo','bar'].map(Function.prototype.call.bind(String.prototype.toUpperCase)) 

或达到相同的效果:

['foo','bar'].map(Function.call.bind("".toUpperCase)) 

JavaScript的处理this是一个坏之旅。

1

你们都错过了这一点。 :-)

我们想在数组的所有元素上调用方法(不是函数)。您可以使用map

a.map(function(x){x.frob()}) 

但这是太多了打字。我们想说:

a.mapm(A.frob) 

其中A是类的amapm元素是一种新的方法Array调用(在这种情况下阵列athis中的每个元素它的参数方法。你可以定义mapm这样的:

Array.prototype.mapm = function (method) 
{ 
    return this.map(function (x) { return method.apply(x) }) 
}; 

,因此称之为:

["a", "b", "c"].mapm("".toUpperCase) ==>  ["A", "B", "C"] 

唯一的问题是,你已经添加了新的元素,mapm每一个阵列,虽然它是由最Array方法忽略,例如lengthmap

+0

+1了解这一点。当然,如果你的代码需要和其他代码一起使用,那么修改Array的原型是有风险的,所以可能需要稍微返工以允许类似以下内容:'a.map(method(“toUpperCase”));函数方法(m){return function(x){return x [m]();}}'另外,一个小的增强也可以允许你通过'method'方法传递一些参数 – 2014-03-14 17:25:31