我正在尝试编写一个函数,它要么接受字符串列表,要么接受单个字符串。如果它是一个字符串,那么我想把它转换成一个只有一个项的数组,这样我就可以在上面循环,而不用担心出错。
那么如何检查变量是否为数组?
我正在尝试编写一个函数,它要么接受字符串列表,要么接受单个字符串。如果它是一个字符串,那么我想把它转换成一个只有一个项的数组,这样我就可以在上面循环,而不用担心出错。
那么如何检查变量是否为数组?
当前回答
function isArray(value) {
if (value) {
if (typeof value === 'object') {
return (Object.prototype.toString.call(value) == '[object Array]')
}
}
return false;
}
var ar = ["ff","tt"]
alert(isArray(ar))
其他回答
此函数将几乎所有内容转换为数组:
function arr(x) {
if(x === null || x === undefined) {
return [];
}
if(Array.isArray(x)) {
return x;
}
if(isString(x) || isNumber(x)) {
return [x];
}
if(x[Symbol.iterator] !== undefined || x.length !== undefined) {
return Array.from(x);
}
return [x];
}
function isString(x) {
return Object.prototype.toString.call(x) === "[object String]"
}
function isNumber(x) {
return Object.prototype.toString.call(x) === "[object Number]"
}
它使用了一些较新的浏览器功能,因此您可能需要对其进行多填充以获得最大支持。
示例:
> arr(null);
[]
> arr(undefined)
[]
> arr(3.14)
[ 3.14 ]
> arr(1/0)
[ Infinity ]
> gen = function*() { yield 1; yield 2; yield 3; }
[Function: gen]
> arr(gen())
[ 1, 2, 3 ]
> arr([4,5,6])
[ 4, 5, 6 ]
> arr("foo")
[ 'foo' ]
N.B.字符串将被转换为具有单个元素的数组,而不是字符数组。如果您希望使用其他方式,请删除isString复选框。
我在这里使用了Array.isArray,因为它是最健壮的,也是最简单的。
虽然有一些可靠的答案,但我更喜欢使用函子的函数方法。函子只是一种奇特的方式,可以说我们将把一个函数传递给一个值。(我看到的建议是将值传递给函数。)
创建TypeOf助手
const TypeOf = obj => Object.prototype.toString.call(obj).slice(8,-1);
这类似于typeof,但现在它为[]返回Array,为{}返回Object。我喜欢把它看作是一种严格的类型。如果你正在使用Gmail应用程序,性能是一个问题,那么你可以这样做。
const TypeOf = obj => (
Array.isArray(obj)
? "array"
: obj === null // catch null edge case. typeof null is an object :)
? null
: typeof obj
)
你可以停下来休息一下。然而,您可以使用合成使其更加强大。如果你创建了一个TypeBox Functor,你会得到很多好处,这也是一个将函数传递给值而不是将值传递给函数的好词。
创建TypeBox
const TypeBox = (predicate, defaultValue) => {
const TypePredicate = value => ({
value,
map: cb => predicate(value)
? TypePredicate(cb(value))
: TypePredicate(defaultValue)
});
return TypePredicate;
}
这里有很多事情,但它非常强大。TypeBox函数使用闭包并返回我们的Functor。闭包允许您访问Lexical_Scope。把它想象成一个背包,里面装着你以后想接触的东西。
创建ArrayBox
const ArrayBox = TypeOf(obj => TypeOf(obj) === 'Array' ? obj : [obj]);
ArrayBox正在将我们的谓词和defaultValue传递给TypeOf,并且在我们调用/执行ArrayBox时将可用(根据您的用例命名)。
现在有趣的部分
如果输入是数组,则返回它。
ArrayBox(["foo", "bar"]).value; // ['foo', 'bar']
如果输入不是数组,请将其返回一个
ArrayBox("foo").value // ["foo"]
这种方法的优点在于它可以扩展,易于测试,并且使用了合成。您可以以任何方式组合函数以获得所需的结果。
我们还有很多其他方法可以使用非此即彼或monads来实现这一点。
这个问题只有一行解决方案
x instanceof Array
其中x是变量,如果x是数组,则返回true,如果不是,则返回false。
检查其原型和Array.isArray之间存在差异:
function isArray(obj){
return Object.getPrototypeOf(obj) === Array.prototype
}
此函数将直接检查obj是否为数组。
但对于此代理对象:
var arr = [1,2,3]
var proxy = new Proxy(arr,{})
console.log(Array.isArray(proxy)) // true
Array.isArray将其作为Array。
A = [1,2,3]
console.log(A.map == [].map)
为了寻找最短的版本,这是我到目前为止得到的。
注意,没有一个完美的函数能够始终检测所有可能的组合。与其期待一个神奇的工具,不如了解工具的所有能力和局限性。