EcmaScript 6
如果您使用的是ES6,则可以构造一系列项目,并使用includes
:
['a', 'b', 'c'].includes('b')
这样做有一些内在的好处,indexOf
因为它可以正确测试NaN
列表中是否存在,并且可以将缺少的数组元素(例如中间的元素)匹配[1, , 2]
到中undefined
。includes
也适用于JavaScript类型的数组,例如Uint8Array
。
如果您担心浏览器支持(例如IE或Edge),可以在CanIUse.Com上进行检查Array.includes
,并且如果要定位缺少的浏览器或浏览器版本,includes
建议使用polyfill.io进行polyfilling。
没有数组
您可以isInList
按如下所示向字符串添加新属性:
if (!String.prototype.isInList) {
String.prototype.isInList = function() {
let value = this.valueOf();
for (let i = 0, l = arguments.length; i < l; i += 1) {
if (arguments[i] === value) return true;
}
return false;
}
}
然后像这样使用它:
'fox'.isInList('weasel', 'fox', 'stoat') // true
'fox'.isInList('weasel', 'stoat') // false
您可以针对做同样的事情Number.prototype
。
Array.indexOf
如果您使用的是现代浏览器,则indexOf
始终可以使用。但是,对于IE8和更早版本,您将需要一个polyfill。
如果indexOf
返回-1,则该项目不在列表中。不过请注意,此方法将无法正确检查NaN
,尽管它可以匹配显式undefined
,但不能将缺少的元素undefined
与array中的匹配[1, , 2]
。
适用于IE indexOf
或includes
IE中的Polyfill ,或任何其他缺少支持的浏览器/版本
如果您不想使用上述提及的polyfill.io之类的服务,则始终可以在自己的源代码中包括符合标准的自定义polyfill。例如,Mozilla Developer Network有一个用于indexOf
。
在这种情况下,我必须为Internet Explorer 7解决方案,我“滚动了自己的” indexOf()
不符合标准的功能的简单版本:
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(item) {
var i = this.length;
while (i--) {
if (this[i] === item) return i;
}
return -1;
}
}
但是,Array.prototype
从长远来看,我认为修改不是最好的答案。用JavaScript 修改Object
和Array
原型可能会导致严重的错误。您需要确定这样做在您自己的环境中是否安全。首先要注意的是,使用进行数组迭代(当Array.prototype添加了属性时)for ... in
将返回新函数名称作为键之一:
Array.prototype.blah = function() { console.log('blah'); };
let arr = [1, 2, 3];
for (let x in arr) { console.log(x); }
// Result:
0
1
2
blah // Extra member iterated over!
您的代码现在可能会工作,但是将来某人添加第三方JavaScript库或插件时,如果他们不热衷于防止继承的键,则一切都可能会中断。
避免破损的旧方法是在枚举期间检查每个值,以查看对象是否实际上将其作为具有非继承属性的对象if (arr.hasOwnProperty(x))
,然后再与该对象一起使用x
。
新ES6的方式来避免这种额外关键的问题是使用of
的,而不是in
,for (let x of arr)
。但是,除非您可以保证所有代码和第三方库都严格遵守此方法,否则出于此问题的目的,您可能只想includes
如上所述使用。