我正在尝试编写一个函数,它要么接受字符串列表,要么接受单个字符串。如果它是一个字符串,那么我想把它转换成一个只有一个项的数组,这样我就可以在上面循环,而不用担心出错。
那么如何检查变量是否为数组?
我正在尝试编写一个函数,它要么接受字符串列表,要么接受单个字符串。如果它是一个字符串,那么我想把它转换成一个只有一个项的数组,这样我就可以在上面循环,而不用担心出错。
那么如何检查变量是否为数组?
当前回答
var length = 16; // Number
var lastName = "Johnson"; // String
var cars = ["Saab", "Volvo", "BMW"]; // Array
var x = {firstName:"John", lastName:"Doe"};
Object.prototype.myCheck= function(){
if (this.constructor === Array){
alert('array');
}else if (this.constructor === Object)
{
alert('object');
}else if (this.constructor === Number)
{
alert('number');
}else if (this.constructor === String)
{
alert('string');
}
}
cars.myCheck();
lastName.myCheck();
length.myCheck();
其他回答
幸运的是,ECMAScript 5在2009年12月引入了Array.isArray()。如果出于某种原因,您使用的JavaScript版本早于ECMAScript 5,请升级。
但是,如果您坚持使用它,那么数组确实具有某些财产,可以将它们与任何其他类型区分开来。我在其他任何答案中都没有提到过的财产。让我们进入一些JavaScript政治。
数组是一个对象(typeof[]==“object”),但与传统对象不同,它们具有长度属性(typeof({}).length==“undefined”)。null也是一个对象(typeof null==“object”),但不能访问null属性,因为null不是对象。
这是规范中的一个bug,可以追溯到JavaScript的最开始,当时对象的类型标记为0,null表示为文本null指针0x00,这导致解释器将其与对象混淆。
不幸的是,这不能解释[]与{length:0}之间的关系。所以我们现在必须转向原型链。
( [] ).__proto__==阵列原型&&([])__原型__!==Object.prototype。
因此,如果没有Array.isArray(),这几乎是我们能得到的最接近的结果:
function is_array(array){
return array !== null
&& typeof array === "object"
&& array.__proto__ === Array.prototype;
}
[ [], [1,2,3], {length: 0}, {},
1, 0, Infinity, NaN, "1", "[1,2,3]",
null, undefined, [null], [undefined], {a:[]},
[{}], [{length: 0}], [Infinity], [NaN],
{__proto__: Array.prototype}
].filter(is_array)
// Expected: [ [], [1,2,3], [null], [undefined], [{}], [{length: 0}], [Infinity], [NaN] ]
// Actual: [ [], [1,2,3], [null], [undefined], [{}], [{length: 0}], [Infinity], [NaN], {__proto__: Array.prototype} ]
被恶意设计成看起来像数组的对象实际上通过了图灵测试。然而,用Array原型链替换原型链就足以使其像数组一样,有效地使其成为数组。
世界上唯一能告诉这样的对象实际上不是数组的是array.isArray()。但出于通常检查对象是否是数组的目的,所述对象应该在代码中表现良好。
甚至当你人为地改变数组长度时的行为也是一样的:如果长度比数组中的元素数长,你会有一个特殊的“隐式未定义”类型的“空槽”,这种类型在某种程度上不同于未定义,同时也是==未定义的;这就是我们使用typeof obj的原因!==“undefined”以避免引发ReferenceError,因为obj==undefineed仅在obj被显式定义为undefine时才会引发错误。
a = {__proto__: Array.prototype}; // Array {}
a.push(5)
a // [5]
a.length = 5
a // [5, empty x 4]
b = a.map(n => n*n) // [25, empty x 4]
b.push(undefined)
b.push(undefined)
b // [25, empty x 4, undefined, undefined]
b[1] // undefined
b[1] === b[5] // true
Array.isArray(a) // false
Array.isArray(b) // true
不过,不要使用is_array()。为了学习目的重新发明轮子是一回事。在生产代码中这样做是另一回事。甚至不要将其用作polyfill。支持旧JavaScript版本意味着支持旧浏览器意味着鼓励使用不安全的软件意味着用户面临恶意软件的风险。
您可以使用Array.isArray()。这里是一个polyfill:
if (Array.isArray == null) {
Array.isArray = (arr) => Object.prototype.toString.call(arr) === "[object Array]"
}
我会制作一个函数来测试您正在处理的对象的类型。。。
函数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
}
你可以试试这个:
var arr = []; (or) arr = new Array();
var obj = {}; (or) arr = new Object();
arr.constructor.prototype.hasOwnProperty('push') //true
obj.constructor.prototype.hasOwnProperty('push') // false
Use:
var is_array = function (value) {
return value &&
typeof value === 'object' &&
typeof value.length === 'number' &&
typeof value.splice === 'function' &&
!(value.propertyIsEnumerable('length'));
};
这个函数取自《JavaScript:TheGoodParts》一书,非常适合我。