我正在尝试编写一个函数,它要么接受字符串列表,要么接受单个字符串。如果它是一个字符串,那么我想把它转换成一个只有一个项的数组,这样我就可以在上面循环,而不用担心出错。
那么如何检查变量是否为数组?
我正在尝试编写一个函数,它要么接受字符串列表,要么接受单个字符串。如果它是一个字符串,那么我想把它转换成一个只有一个项的数组,这样我就可以在上面循环,而不用担心出错。
那么如何检查变量是否为数组?
当前回答
我会制作一个函数来测试您正在处理的对象的类型。。。
函数whatAmI(me){return Object.pr原型.toString.call(me).split(/\W/)[2];}//测试控制台日志(whatAmI([“瞄准”,“@”]),whatAmI({生活:4,呼吸:4}),whatAmI(函数(ing){return ing+“到全局窗口”}),我(“要和你做什么?”));//输出:数组对象函数字符串
然后你可以写一个简单的if语句。。。
if(whatAmI(myVar) === "Array"){
// do array stuff
} else { // could also check `if(whatAmI(myVar) === "String")` here to be sure
// do string stuff
}
其他回答
Array.isArray工作速度很快,但并非所有版本的浏览器都支持它。
因此,您可以为其他人创建例外,并使用通用方法:
Utils = {};
Utils.isArray = ('isArray' in Array) ?
Array.isArray :
function (value) {
return Object.prototype.toString.call(value) === '[object Array]';
}
正如MDN在这里所说:
使用Array.isArray或Object.prototype.toString.call进行区分阵列中的常规对象
这样地:
Object.pr原型.toString.call(arr)==“[对象数组]”,或Array.isArray(arr)
检查其原型和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。
因为我不喜欢任何Object.prototype调用,所以我寻找了另一种解决方案。特别是因为ChaosPandion的解决方案并不总是有效的,并且MidnightTortoise的isArray()解决方案不适用于来自DOM的数组(如getElementsByTagName)。最后,我找到了一个简单的跨浏览器解决方案,这可能也适用于Netscape 4
只有这四行(检查任何对象h):
function isArray(h){
if((h.length!=undefined&&h[0]!=undefined)||(h.length===0&&h[0]===undefined)){
return true;
}
else{ return false; }
}
我已经测试了这些数组(全部返回true):
1) array=d.getElementsByName('some_element'); //'some_element' can be a real or unreal element
2) array=[];
3) array=[10];
4) array=new Array();
5) array=new Array();
array.push("whatever");
这适用于所有情况吗?或者我的解决方案不起作用?
虽然有一些可靠的答案,但我更喜欢使用函子的函数方法。函子只是一种奇特的方式,可以说我们将把一个函数传递给一个值。(我看到的建议是将值传递给函数。)
创建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来实现这一点。