在 SQL 中,我们可以查看字符串是否在列表中,如下所示:
Column IN ('a', 'b', 'c')
在 JavaScript 中这样做的好方法是什么?这样做很笨拙:
if (expression1 || expression2 || str === 'a' || str === 'b' || str === 'c') {
// do something
}
我不确定它的性能或清晰度:
if (expression1 || expression2 || {a:1, b:1, c:1}[str]) {
// do something
}
或者可以使用 switch 功能:
var str = 'a',
flag = false;
switch (str) {
case 'a':
case 'b':
case 'c':
flag = true;
default:
}
if (expression1 || expression2 || flag) {
// do something
}
但这是一个可怕的困惑。有任何想法吗?
在这种情况下,我必须使用 Internet Explorer 7,因为它用于公司内部网页。所以
['a', 'b', 'c'].indexOf(str) !== -1
如果没有一些语法糖,将无法在本地工作。
最佳答案
EcmaScript 6 及更高版本
如果您使用 ES6 或更高版本,最简洁的方法是构造一个项目数组并使用 Array.includes
:
['a', 'b', 'c'].includes('b')
这比 indexOf
有一些内在的好处。因为它可以正确测试 NaN
的存在在列表中,并且可以匹配缺失的数组元素,例如 [1, , 2]
中的中间元素至 undefined
. includes
也适用于 JavaScript typed arrays如 Uint8Array
.如果您担心浏览器支持(例如 IE 或 Edge),您可以 check
Array.includes
at CanIUse.Com ,如果您想定位缺少的浏览器或浏览器版本 includes
, 我推荐 polyfill.io用于填充。没有数组
您可以添加一个新的
isInList
字符串的属性如下:if (!String.prototype.isInList) {
Object.defineProperty(String.prototype, 'isInList', {
get: () => function(...args) {
let value = this.valueOf();
for (let i = 0, l = args.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
做同样的事情.请注意
Object.defineProperty
不能在 IE8 及更早版本,或其他浏览器的非常旧版本中使用。然而,它是比 String.prototype.isInList = function() { ... }
优越得多的解决方案。因为使用这样的简单赋值会在 String.prototype
上创建一个可枚举的属性。 ,这更有可能破坏代码。数组索引
如果您使用的是现代浏览器,
indexOf
总是有效。但是,对于 IE8 及更早版本,您将需要一个 polyfill。如
indexOf
返回 -1,该项目不在列表中。但请注意,此方法无法正确检查 NaN
, 虽然它可以匹配显式 undefined
,它无法将缺失的元素匹配到 undefined
如数组 [1, , 2]
.Polyfill for
indexOf
或 includes
在 IE 或任何其他缺乏支持的浏览器/版本中如果您不想使用像 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
从长远来看是最好的答案。修改 Object
和 Array
JavaScript 中的原型(prototype)可能会导致严重的错误。您需要决定这样做在您自己的环境中是否安全。主要注意的是使用 for ... in
迭代数组(当 Array.prototype 添加了属性时)将返回新函数名称作为键之一: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 库或插件,而这些库或插件并没有积极防范继承的 key ,那么一切都可能会崩溃。避免这种破坏的旧方法是在枚举期间检查每个值以查看对象是否确实将其作为非继承属性使用
if (arr.hasOwnProperty(x))
然后才使用该 x
.避免这个额外关键问题的新 ES6 方法是:
of
而不是 in
, for (let x of arr)
.但是,除非您能保证您的所有代码和第三方库都严格遵守此方法,否则就本问题而言,您可能只想使用 includes
如上所述。Object.defineProperty()
在原型(prototype)上定义新属性,因为这将使属性(默认情况下)不可枚举。只有当您使用的所有 JavaScript 库或模块都这样做时,这才真正解决了问题。关于javascript - 确定字符串是否在 JavaScript 中的列表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2430000/