提问人:mpen 提问时间:1/24/2011 最后编辑:jonrsharpempen 更新时间:8/31/2021 访问量:2024792
如何检查对象是否为数组?[复制]
How can I check if an object is an array? [duplicate]
问:
我正在尝试编写一个接受字符串列表或单个字符串的函数。如果它是一个字符串,那么我想将其转换为只有一个项目的数组,这样我就可以遍历它而不必担心出错。
那么如何检查变量是否为数组呢?
答:
ECMAScript 标准中给出的查找 Object 类的方法是使用 中的方法。toString
Object.prototype
if(Object.prototype.toString.call(someVar) === '[object Array]') {
alert('Array!');
}
或者你可以用它来测试它是否是一个字符串:typeof
if(typeof someVar === 'string') {
someVar = [someVar];
}
或者,如果您不关心性能,则可以对新的空数组执行操作。concat
someVar = [].concat(someVar);
还有可以直接查询的构造函数:
if (somevar.constructor.name == "Array") {
// do something
}
查看 TJ Crowder 博客中的彻底治疗,如他在下面的评论中所发布的那样。
查看此基准测试,了解哪种方法性能更好: http://jsben.ch/#/QgYAV
在 @Bharath 中,使用 ES6 将字符串转换为数组,以解决所提出的问题:
const convertStringToArray = (object) => {
return (typeof object === 'string') ? Array(object) : object
}
假设:
let m = 'bla'
let n = ['bla','Meow']
let y = convertStringToArray(m)
let z = convertStringToArray(n)
console.log('check y: '+JSON.stringify(y)) . // check y: ['bla']
console.log('check y: '+JSON.stringify(z)) . // check y: ['bla','Meow']
评论
toString
Array.isArray(obj)
我会首先检查您的实现是否支持:isArray
if (Array.isArray)
return Array.isArray(v);
您也可以尝试使用运算符instanceof
v instanceof Array
评论
v instanceof Array
如果在另一个帧中创建(是类的实例),将返回 false。v
v
thatFrame.contentWindow.Array
Array.isArray
被定义为 ECMAScript 5/Javascript 1.8.5 的一部分。
如果可以传递给此函数的只有两种值是字符串或字符串数组,请保持简单,并检查字符串的可能性:typeof
function someFunc(arg) {
var arr = (typeof arg == "string") ? [arg] : arg;
}
评论
我见过的最好的解决方案是跨浏览器替换 typeof。查看安格斯·克罗尔(Angus Croll)的解决方案。
The TL;DR 版本在下面,但这篇文章对这个问题进行了很好的讨论,所以如果你有时间,你应该阅读它。
Object.toType = function(obj) {
return ({}).toString.call(obj).match(/\s([a-z|A-Z]+)/)[1].toLowerCase();
}
// ... and usage:
Object.toType([1,2,3]); //"array" (all browsers)
// or to test...
var shouldBeAnArray = [1,2,3];
if(Object.toType(shouldBeAnArray) === 'array'){/* do stuff */};
jQuery 还提供了一个 $.isArray()
方法:
var a = ["A", "AA", "AAA"];
if($.isArray(a)) {
alert("a is an array!");
} else {
alert("a is not an array!");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
评论
我知道,人们正在寻找某种原始的 JavaScript 方法。但是,如果你想少想一点,看看Underscore.js的isArray:
_.isArray(object)
如果 object 是 Array,则返回 true。
(function(){ return _.isArray(arguments); })();
=> false
_.isArray([1,2,3]);
=> true
评论
我会做一个函数来测试你正在处理的对象类型......
function whatAmI(me){ return Object.prototype.toString.call(me).split(/\W/)[2]; }
// tests
console.log(
whatAmI(["aiming","@"]),
whatAmI({living:4,breathing:4}),
whatAmI(function(ing){ return ing+" to the global window" }),
whatAmI("going to do with you?")
);
// output: Array Object Function String
然后你可以写一个简单的 if 语句......
if(whatAmI(myVar) === "Array"){
// do array stuff
} else { // could also check `if(whatAmI(myVar) === "String")` here to be sure
// do string stuff
}
一个简单的函数来检查这一点:
function isArray(object)
{
return object.constructor === Array;
}
评论
return object.constructor === Array
if(x) return true; else return false
正如 MDN 在这里所说:
使用 Array.isArray 或 Object.prototype.toString.call 来区分 数组中的常规对象
喜欢这个:
Object.prototype.toString.call(arr) === '[object Array]'
或Array.isArray(arr)
Array.isArray 运行速度很快,但并非所有版本的浏览器都支持它。
因此,您可以为其他人设置例外并使用通用方法:
Utils = {};
Utils.isArray = ('isArray' in Array) ?
Array.isArray :
function (value) {
return Object.prototype.toString.call(value) === '[object Array]';
}
评论
这是我的懒惰方法:
if (Array.prototype.array_ === undefined) {
Array.prototype.array_ = true;
}
// ...
var test = [],
wat = {};
console.log(test.array_ === true); // true
console.log(wat.array_ === true); // false
我知道“弄乱”原型是亵渎神明的,但它的性能似乎比推荐的 toString
方法要好得多。
注意:这种方法的一个缺陷是它不能跨 iframe
边界工作,但对于我的用例来说,这不是问题。
评论
wat = {array_: true}
obj.array_ = true
cache
array_
.array_
.array
.__isArray = true
您可以检查变量的类型是否为数组;
var myArray=[];
if(myArray instanceof Array)
{
....
}
评论
instanceof
由于我不喜欢任何 Object.prototype 调用,因此我搜索了另一种解决方案。特别是因为 ChaosPandion 的解决方案并不总是有效,而 MidnightTortoise 的解决方案不适用于来自 DOM 的数组(如 getElementsByTagName)。最后,我找到了一个简单的跨浏览器解决方案,它可能也适用于 Netscape 4。;)isArray()
只有这四行(检查任何对象):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");
这是否适用于所有情况?或者我的解决方案是否不起作用?
评论
isArray(function(){}); // true
isArray("foo"); // true
isArray({length:0}); // true
alert("foo".constructor);
var bar=["id","12345"]; alert(bar.constructor);
foobar={"id":"12345"};
alert(foobar.constructor);
您可以使用 Array.isArray()。下面是一个 polyfill:
if (Array.isArray == null) {
Array.isArray = (arr) => Object.prototype.toString.call(arr) === "[object Array]"
}
评论
A = [1,2,3]
console.log(A.map == [].map)
为了寻找最短的版本,这是我到目前为止得到的。
请注意,没有完美的函数可以始终检测所有可能的组合。了解工具的所有功能和局限性比期望神奇的工具要好。
评论
A.map !== undefined
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))
评论
Stoyan Stefanov 的《JavaScript Patterns》一书中有一个很好的例子,它应该处理所有可能的问题,并使用 ECMAScript 5 方法 Array.isArray()。
所以这里是:
if (typeof Array.isArray === "undefined") {
Array.isArray = function (arg) {
return Object.prototype.toString.call(arg) === "[object Array]";
};
}
顺便说一句,如果你使用的是jQuery,你可以使用它的方法$.isArray()。
评论
if(!Array.isArray) {...
在现代浏览器中,您可以执行以下操作:
Array.isArray(obj)
(基金资助Chrome 5、Firefox 4.0、Internet Explorer 9、Opera 10.5 和 Safari 5)
为了向后兼容,您可以添加以下内容:
// Only implement if no native implementation is available
if (typeof Array.isArray === 'undefined') {
Array.isArray = function(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
};
如果使用 jQuery,则可以使用 或 .如果使用 Underscore.js,则可以使用 .jQuery.isArray(obj)
$.isArray(obj)
_.isArray(obj)
如果你不需要检测在不同帧中创建的数组,你也可以只使用:instanceof
obj instanceof Array
评论
instanceof Array
Array
Object
Object
Array
用于测试输入值是否为数组的简单函数如下:
function isArray(value)
{
return Object.prototype.toString.call(value) === '[object Array]';
}
这适用于跨浏览器和较旧的浏览器。这是从 T.J. Crowders 的博客文章中摘录的
这是我在考虑评论后改进此答案的尝试:
var isArray = myArray && myArray.constructor === Array;
它删除了 if/else,并考虑了数组为 null 或未定义的可能性
评论
我以一种非常简单的方式做到这一点。它对我有用。
Array.prototype.isArray = true;
a=[]; b={};
a.isArray // true
b.isArray // (undefined -> false)
评论
{isArray:true}
JSON.parse(someDataFromElsewhere).items.isArray
可能会返回 true(取决于数据)并破坏您的代码。
这是我想出并一直用于我的项目的解决方案......
function isArray (o) {
return typeof o === "object" && o.length !== undefined;
}
isArray({}); // false
isArray(1); // false
isArray("str"); // false
isArray(function(){}); // false
isArray([]); // true
唯一的缺陷是,如果你的对象恰好有一个长度属性,它会给出误报:
isArray({length:0}); // true
如果你对这个缺点感到满意,并且知道你的纯对象不会有这个属性,那么它是一个干净的解决方案,应该比 Object.prototype.toString.call 方法更快。
评论
用:
var is_array = function (value) {
return value &&
typeof value === 'object' &&
typeof value.length === 'number' &&
typeof value.splice === 'function' &&
!(value.propertyIsEnumerable('length'));
};
这个函数取自“JavaScript: The Good Parts”一书,它对我来说非常有效。
评论
var object = {splice: function(){}}; Object.defineProperty(object, "length", {value: 1, enumerable: false}); console.log(is_array(object));
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();
评论
cars.myCheck()
obj
this
我已经用两种替代方法更新了 jsperf 小提琴以及错误检查。
事实证明,在“Object”和“Array”原型中定义常量值的方法比任何其他方法都快。这是一个有点令人惊讶的结果。
/* Initialisation */
Object.prototype.isArray = function() {
return false;
};
Array.prototype.isArray = function() {
return true;
};
Object.prototype._isArray = false;
Array.prototype._isArray = true;
var arr = ["1", "2"];
var noarr = "1";
/* Method 1 (function) */
if (arr.isArray()) document.write("arr is an array according to function<br/>");
if (!noarr.isArray()) document.write("noarr is not an array according to function<br/>");
/* Method 2 (value) - **** FASTEST ***** */
if (arr._isArray) document.write("arr is an array according to member value<br/>");
if (!noarr._isArray) document.write("noarr is not an array according to member value<br/>");
如果变量采用未定义的值,则这两种方法不起作用,但如果您确定它们具有值,则它们确实有效。关于检查性能是值是数组还是单个值,第二种方法看起来像一个有效的快速方法。它比 Chrome 上的“instanceof”略快,是 Internet Explorer、Opera 和 Safari(在我的机器上)中第二好方法的两倍。
这是所有方法中最快的(支持所有浏览器):
function isArray(obj){
return !!obj && obj.constructor === Array;
}
你可以试试这个:
var arr = []; (or) arr = new Array();
var obj = {}; (or) arr = new Object();
arr.constructor.prototype.hasOwnProperty('push') //true
obj.constructor.prototype.hasOwnProperty('push') // false
您可以使用此函数获取数据类型。
var myAr = [1,2];
checkType(myAr);
function checkType(data) {
if(typeof data ==='object') {
if(Object.prototype.toString.call(data).indexOf('Array') !== (-1)) {
return 'array';
} else {
return 'object';
}
} else {
return typeof data;
}
}
if(checkType(myAr) === 'array') {
console.log('yes, it is an array')
};
评论
如果您知道您的对象没有 concat 方法,则可以使用以下内容。
var arr = [];
if (typeof arr.concat === 'function') {
console.log("It's an array");
}
评论
这个函数会把几乎任何东西变成一个数组:
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]"
}
它使用一些较新的浏览器功能,因此您可能希望对其进行 polyfill 以获得最大的支持。
例子:
> 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' ]
注意字符串将被转换为具有单个元素的数组,而不是字符数组。如果您希望以相反的方式删除该检查。isString
我在这里使用它是因为它最强大,也是最简单的。Array.isArray
想象一下,你下面有这个数组:
var arr = [1,2,3,4,5];
JavaScript(新旧浏览器):
function isArray(arr) {
return arr.constructor.toString().indexOf("Array") > -1;
}
或
function isArray(arr) {
return arr instanceof Array;
}
或
function isArray(arr) {
return Object.prototype.toString.call(arr) === '[object Array]';
}
然后这样称呼它:
isArray(arr);
JavaScript(Internet Explorer 9+、Chrome 5+、Firefox 4+、Safari 5+ 和 Opera 10.5+)
Array.isArray(arr);
j查询:
$.isArray(arr);
角:
angular.isArray(arr);
下划线.js和 Lodash:
_.isArray(arr);
检查对象是否为数组的最简单、最快捷的方法。
var arr = [];
arr.constructor.name === 'Array' // Returns true;
或
arr.constructor === Array // Returns true;
或者你可以做一个实用函数:
const isArray = (obj) => !!obj && obj.constructor === Array;
用法:
isArray(arr); // Returns true
您可以在下面找到:push
function isArray(obj){
return (typeof obj.push === 'function') ? true : false;
}
var array = new Array();
or
var array = ['a', 'b', 'c'];
console.log(isArray(array));
这个问题只有一行解决方案
x instanceof Array
其中 x 是变量,如果 x 是数组,它将返回 true,如果不是,则返回 false。
在您的情况下,您可以使用 Array 方法,它可以接受单个对象以及数组(甚至组合):concat
function myFunc(stringOrArray)
{
var arr = [].concat(stringOrArray);
console.log(arr);
arr.forEach(function(item, i)
{
console.log(i, "=", item);
})
}
myFunc("one string");
myFunc(["one string", "second", "third"]);
concat
似乎是最古老的 Array 方法之一(即使是 IE 5.5 也很清楚)。
您可以使用 isArray 方法,但我更愿意检查:
Object.getPrototypeOf(yourvariable) === Array.prototype
评论
Object.getPrototypeOf(yourvariable)
这是我使用的:
function isArray(input) {
if (input instanceof Array || Object.prototype.toString.call(input) === '[object Array]') {
return true;
} else return false;
}
值得庆幸的是,ECMAScript 5 早在 2009 年 12 月就推出了。如果由于某种原因,您使用的 JavaScript 版本早于 ECMAScript 5,请升级。Array.isArray()
但是,如果您坚持这样做,那么数组确实具有某些属性,可以将它们与任何其他类型区分开来。我在任何其他答案中都没有看到的属性。让我们来谈谈 JavaScript 政治。
数组是一个对象 (),但与传统对象不同的是,它们具有长度属性 ()。 也是一个对象 (),但你不能访问 因为不是对象的属性。typeof [] === "object"
typeof ( {} ).length === "undefined"
null
typeof null === "object"
null
null
这是规范中的一个错误,可以追溯到 JavaScript 的最初阶段,当时对象具有 type 标签并表示为 literal null 指针 ,这导致解释器将其与对象混淆。0
null
0x00
不幸的是,这没有考虑到 vs.因此,我们现在必须转向原型链。[]
{length:0}
( [] ).__proto__ === Array.prototype && ( [] ).__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()
甚至当你人为地改变数组的长度时,行为也是相同的:如果长度长于数组中的元素数,你将拥有那种特殊的“隐式未定义”类型的“空槽”,这种类型在某种程度上与未定义不同,同时也是;与我们用来避免抛出 a 的类型完全相同,因为 only 如果显式定义为 ,则不会抛出错误。=== undefined
typeof obj !== "undefined"
ReferenceError
obj === undefined
obj
undefined
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
不过不要使用。出于学习目的重新发明轮子是一回事。在生产代码中执行此操作是另一回事。甚至不要将其用作 polyfill。支持旧的 JavaScript 版本意味着支持旧的浏览器意味着鼓励使用不安全的软件意味着将用户置于恶意软件的风险之中。is_array()
评论
is_array
__proto__
Array.prototype
Array.isArray
您还可以检查数组的 length 属性。当您尝试访问数组的 length 属性时,它将返回一个数字(0 表示空数组),而如果您尝试访问 object 的 length 属性,它将返回 undefined。
if(Object.prototype.toString.call(arrayList) === '[object Array]') {
console.log('Array!');
}
评论
.length
{length:5}
繁荣。具有 Length 属性的对象。
也存在其他检查方法,但我更喜欢以下方法作为我最好的检查方法(因为您可以轻松检查其他对象的类型)。
> a = [1, 2]
[ 1, 2 ]
>
> Object.prototype.toString.call(a).slice(8,).replace(/\]$/, '')
'Array'
>
> Object.prototype.toString.call([]).slice(8,-1) // best approach
'Array'
解释(在 Node REPL 上提供简单示例)»
> o = {'ok': 1}
{ ok: 1 }
> a = [1, 2]
[ 1, 2 ]
> typeof o
'object'
> typeof a
'object'
>
> Object.prototype.toString.call(o)
'[object Object]'
> Object.prototype.toString.call(a)
'[object Array]'
>
对象或数组 »
> Object.prototype.toString.call(o).slice(8,).replace(/\]$/, '')
'Object'
>
> Object.prototype.toString.call(a).slice(8,).replace(/\]$/, '')
'Array'
>
Null 或 Undefined »
> Object.prototype.toString.call(undefined).slice(8,).replace(/\]$/, '')
'Undefined'
> Object.prototype.toString.call(null).slice(8,).replace(/\]$/, '')
'Null'
>
字符串 »
> Object.prototype.toString.call('ok').slice(8,).replace(/\]$/, '')
'String'
数字 »
> Object.prototype.toString.call(19).slice(8,).replace(/\]$/, '')
'Number'
> Object.prototype.toString.call(19.0).slice(8,).replace(/\]$/, '')
'Number'
> Object.prototype.toString.call(19.7).slice(8,).replace(/\]$/, '')
'Number'
>
我很欣赏使用 -1 代替正则表达式的建议,如下所示。@mpen
> Object.prototype.toString.call(12).slice(8,-1)
'Number'
>
> Object.prototype.toString.call(12.0).slice(8,-1)
'Number'
>
> Object.prototype.toString.call([]).slice(8,-1)
'Array'
> Object.prototype.toString.call({}).slice(8,-1)
'Object'
>
> Object.prototype.toString.call('').slice(8,-1)
'String'
>
评论
-1
slice
@mpen
检查其原型和 Array.isArray 之间是有区别的:
function isArray(obj){
return Object.getPrototypeOf(obj) === Array.prototype
}
此函数将直接检查 obj 是否为数组。
但是对于这个 Proxy 对象:
var arr = [1,2,3]
var proxy = new Proxy(arr,{})
console.log(Array.isArray(proxy)) // true
Array.isArray
将它作为 Array。
评论
isArray
true
这里有一个代码片段,它将解释数组的一个重要事实,在学习 JavaScript 时应该尽早知道这个事实(与我不同)。
// this functions puts a string inside an array
var stringInsideArray = function(input) {
if (typeof input === 'string') {
return [input];
}
else if (Array.isArray(input)) {
return input;
}
else {
throw new Error("Input is not a string!");
}
}
var output = stringInsideArray('hello');
console.log('step one output: ', output); // ["hello"]
// use typeof method to verify output is an object
console.log('step two output: ', typeof output); // object
// use Array.isArray() method to verify output is an array
console.log('step three output: ', Array.isArray(output)); // true
数组实际上是对象。
使用 typeof 运算符,证明 的输出确实是一个对象。这让我困惑了很长一段时间,因为我认为数组将是一种 JavaScript 数据类型......stringInsideArray('hello')
["hello"]
只有七种 JavaScript 数据类型,数组不是其中之一。
要回答您的问题,请使用 Array.isArray() 方法确定 是一个数组。output
评论
[].concat(string)
[string]
function toArray(x) { if(x === undefined) return []; if(Array.isArray(x)) return x; return [x]; }
或者可能是中间情况,具体取决于您是否希望返回新数组。[...x]
throw new Error("Input is not a string!")
最佳做法是使用 进行比较,如下所示constructor
if(some_variable.constructor === Array){
// do something
}
您也可以使用其他方法,例如,将其转换为字符串然后进行比较,但将其与 dataType 进行比较始终是更好的方法。typeOf
我现在找到了最简短的答案:
var x = [1,2,3]
console.log(x.map?1:0)
评论
? 1 : 0
!!x.map
x.map
Array.isArray
是解决这个问题的方法。例如:
var arr = ['tuna', 'chicken', 'pb&j'];
var obj = {sandwich: 'tuna', chips: 'cape cod'};
// Returns true
Array.isArray(arr);
// Return false
Array.isArray(obj);
首先,您可以检查 console.log(typeof Object)。
如果输出是 object,则 var {data}=object,即根据对象键对对象进行解构。
函数可以是这样的:
const abc = (str1, str2=null) => {
var result = [];
result.push(str1);
result.push(str2);
return result.join("");
}
评论
typeof []
typeof ""
typeof new String('')
虽然有一些可靠的答案,但我更喜欢使用函子的函数式方法。函子只是一种奇特的说法,即我们将函数传递给一个值。(我看到的建议是将值传递给函数。
创建 TypeOf 帮助程序
const TypeOf = obj => Object.prototype.toString.call(obj).slice(8,-1);
这类似于 typeof,但它现在返回 for 和 for 。我喜欢把它看作是一种严格的类型。如果您正在使用Gmail应用程序并且性能是一个问题,那么您可以执行类似操作。Array
[]
Object
{}
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 函数使用闭包并返回我们的函子。关闭允许您访问Lexical_Scope。把它想象成一个背包,里面装着你以后想拿到的东西。
创建 ArrayBox
const ArrayBox = TypeOf(obj => TypeOf(obj) === 'Array' ? obj : [obj]);
ArrayBox 将我们的 and 传递给 并且将在我们调用/执行时可用(将其命名为对您的用例有意义的任何名称)。predicate
defaultValue
TypeOf
ArrayBox
现在是有趣的部分
如果输入是 Array,则返回它。
ArrayBox(["foo", "bar"]).value; // ['foo', 'bar']
如果输入不是数组,则将其返回为一个数组
ArrayBox("foo").value // ["foo"]
这种方法的优点在于它可以扩展,易于测试,并且使用组合。您可以以任何方式组合函数以获得所需的结果。
我们可以通过许多其他方法使用 Either 或 monads 来解决这个问题。
var a = [], b = {};
console.log(a.constructor.name == "Array");
console.log(b.constructor.name == "Object");
评论
异国情调的
您想检查参数是否为字符串 - 所以尝试
x===x+''
let isStr = x=> x===x+'';
console.log( isStr([]) );
console.log( isStr(["aa","bb"]) );
console.log( isStr("") );
console.log( isStr("abc") );
评论
Array.isArray(obj) 不会给出非常有用的结果。我创建了一个 Object 的原型方法,它似乎可以正确确定 object 是否是数组。
据我所知,它失败的唯一边缘情况是数组中的项设置为未定义时。
Object.prototype.isArrayLike = function()
{
var length = this.length || Object.keys(this).length;
if (length === 0 || this.constructor.name === "String")
return false;
for (i = 0; i < length; i++)
{
if (typeof this[i] === "undefined")
return false;
}
return true;
};
var arr = ['aaa', 'bbb', 'ccc', 'ddd'];
var arr1 = {"0":'aaa', "1":'bbb', 2:'ccc', 3:'ddd'};
var arr2 = {"0":'aaa', "a":'bbb', 2:'ccc', 3:'ddd'};
var arr3 = "qwerty";
var arr4 = [];
var arr5 = {0:'aaa', 1:'bbb', 2:'ccc', 3:'ddd'};
console.log("arrayLike:" + arr.isArrayLike());
console.log("Array.isArray(arr):" + Array.isArray(arr));
// arrayLike: true
// Array.isArray(arr): true
console.log("arrayLike1:" + arr1.isArrayLike());
console.log("Array.isArray(arr1):" + Array.isArray(arr1));
// arrayLike1: true
// Array.isArray(arr1): false
console.log("arrayLike2:" + arr2.isArrayLike());
console.log("Array.isArray(arr2):" + Array.isArray(arr2));
// arrayLike2: false
// Array.isArray(arr2): false
console.log("arrayLike3:" + arr3.isArrayLike());
console.log("Array.isArray(arr3):" + Array.isArray(arr3));
// arrayLike3: false
// Array.isArray(arr3): false
console.log("arrayLike4:" + arr4.isArrayLike());
console.log("Array.isArray(arr4):" + Array.isArray(arr4));
// arrayLike4: false
// Array.isArray(arr4): true
console.log("arrayLike5:" + arr5.isArrayLike());
console.log("Array.isArray(arr5):" + Array.isArray(arr5));
// arrayLike5: false
// Array.isArray(arr5): true
以简单的方式
const arr = [1, 2, 3];
const obj = { message: 'nice' };
const str = 'nice';
const empty = null;
console.log(Array.isArray(arr));
console.log(Array.isArray(obj));
console.log(Array.isArray(str));
console.log(Array.isArray(empty));
评论
下一个:如何将某些内容附加到数组中?
评论
arr.constructor === Array
arr.constructor === Array
Array.isArray(arr)