为什么我可以在不是数组的对象上调用Array.prototype.filter()?

问题描述:

filter Creates a new array with all elements that pass 
      the test implemented by the provided function. 

>>> 'abc'.filter(function(e){return e!='b'}) 
TypeError: "abc".filter is not a function 

>>> Array.prototype.filter.call('abc', function(e){return e!='b'}) 
["a", "c"] 

>>> jQuery.isArray('abc') 
false 
+1

没有线索。 'Array.filter'不存在。你是不是指'Array.prototype.filter.call'? – Ryan 2012-04-15 03:25:11

+0

@minitech是的。你是对的 – kev 2012-04-15 03:26:03

+0

@minitech'Array.filter'存在于Firefox中。 – Pointy 2012-04-15 03:27:47

所有阵列方法是通用的;即它们在具有数字属性加上length属性的任何对象上工作。见the specification for Array.prototype.filter,例如:请注意,该算法在物联网方面完全一样的措辞

lenValue是调用的O[[Get]]内部方法与参数"length"的结果。

kPresent是调用的O[[HasProperty]]内部方法与参数Pk的结果。


Array.filtera Firefox-specific extension,BTW。跨浏览器版本是Array.prototype.filter.call

+0

我更新了底部的注释,但是我不能让String.filter在FF中工作,所以这部分可能不准确......或者我完全错过了试图说的东西。 Array.filter是每个第5版或JS 1.6 ...和'arr.filter'将工作在任何地方'Array.prototype.filter.call'工作(String!= Array)。无论如何,希望这个评论将达到你:) – 2012-04-15 03:51:24

+0

'Array.filter'没有在ES5规范中指定。它是每个JS 1.6,这是一个Mozilla特定的扩展。删除编辑。 – Domenic 2012-04-15 18:28:41

您可以这样做,因为Array.filter 被定义为通用的;例如,您可以拨打NodeList。这对开发人员来说只是一个方便。这也适用于字符串,因为在现代浏览器(一切,除了IE 8和更早的版本),你可以访问字符串中的字符,就像您数组的索引,而这正是filter是基于与length一起:

var str = "Hello, world!"; 

str[2] // 'l' 

但是,如果您计划支持Internet Explorer 8或更早版本,我不会推荐使用此功能,因为ES5 shivs可能无法检测到上下文是字符串,这会破坏事情。

以及所有其他Array方法。除此之外,再次使用Internet Explorer 8和更早的版本。

+0

最广泛使用的es5垫片(kriskowal/es5-shim)实际上可以在非数组对象上正常工作。 – Domenic 2012-04-15 03:33:42