我正在尝试编写一个接受字符串列表或单个字符串的函数。如果它是一个字符串,那么我想将它转换为只有一个项目的数组。然后我可以循环它而不用担心错误。
那么如何检查变量是否是数组?
我已经完成了下面的各种解决方案并创建了jsperf test。
答案 0 :(得分:1900)
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
}
查看thorough treatment博客中的@T.J. Crowder's,如下面的评论所示。
查看此benchmark以了解哪种方法效果更佳: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']
答案 1 :(得分:1243)
我首先会检查您的实施是否支持isArray
:
if (Array.isArray)
return Array.isArray(v);
您也可以尝试使用instanceof
运算符
v instanceof Array
答案 2 :(得分:654)
在现代浏览器中,您可以
Array.isArray(obj)
(Supported by Chrome 5,Firefox 4.0,IE 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,则可以使用jQuery.isArray(obj)
或$.isArray(obj)
。如果您使用下划线,则可以使用_.isArray(obj)
如果您不需要检测在不同帧中创建的数组,您也可以使用instanceof
obj instanceof Array
答案 3 :(得分:289)
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>
答案 4 :(得分:93)
这是所有方法中最快的(支持所有浏览器):
function isArray(obj){
return !!obj && obj.constructor === Array;
}
答案 5 :(得分:36)
想象一下,下面有这个数组:
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(IE9 +,Ch5 +,FF4 +,Saf5 +,Opera10.5 +)
Array.isArray(arr);
jQuery的:
$.isArray(arr);
角:
angular.isArray(arr);
下划线和Lodash:
_.isArray(arr);
答案 6 :(得分:32)
Array.isArray运行速度很快,但并不是所有版本的浏览器都支持它。 所以你可以为其他人做一个例外并使用通用方法:
Utils = {};
Utils.isArray = ('isArray' in Array) ?
Array.isArray :
function (value) {
return Object.prototype.toString.call(value) === '[object Array]';
}
答案 7 :(得分:22)
检查此功能的简单功能:
function isArray(object)
{
if (object.constructor === Array) return true;
else return false;
}
答案 8 :(得分:15)
这个问题只有一行解决方案
x instanceof Array
其中x是变量,如果x是数组,它将返回true,如果不是则返回false。
答案 9 :(得分:13)
我会创建一个函数来测试你正在处理的对象的类型......
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
}
答案 10 :(得分:13)
您可以检查变量的类型是否为带有;
的数组var myArray=[];
if(myArray instanceof Array)
{
....
}
答案 11 :(得分:11)
我以非常简单的方式做到这一点。适合我。有什么缺点吗?
Array.prototype.isArray = true;
a=[]; b={};
a.isArray // true
b.isArray // (undefined -> false)
答案 12 :(得分:11)
考虑到这些评论,我试图改进this answer:
var isArray = myArray && myArray.constructor === Array;
它摆脱了if / else,并说明了数组为null或未定义的可能性
答案 13 :(得分:10)
我已使用两种替代方法更新了jsperf fiddle以及错误检查。
事实证明,该方法在&#39;对象&#39;中定义了一个常量值。和&#39;阵列&#39;原型比任何其他方法都快。这是一个有点令人惊讶的结果。
/* 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/>");
&#13;
如果变量采用未定义的值,则这两种方法不起作用,但如果您确定它们具有值,则它们可以正常工作。关于如果值是数组或单个值而考虑性能,第二种方法看起来像一个有效的快速方法。它比“实例”快一点。在Chrome上,速度是Internet Explorer,Opera和Safari(在我的机器上)中第二好的方法的两倍。
答案 14 :(得分:10)
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/isArray
Array.isArray = Array.isArray || function (vArg) {
return Object.prototype.toString.call(vArg) === "[object Array]";
};
答案 15 :(得分:9)
我知道,人们正在寻找某种原始的javascript方法。 但如果你想减少思考,请看一下:http://underscorejs.org/#isArray
_.isArray(object)
如果object是一个数组,则返回true。
(function(){ return _.isArray(arguments); })();
=> false
_.isArray([1,2,3]);
=> true
答案 16 :(得分:5)
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()
答案 17 :(得分:5)
你可能是isArray方法,但我更愿意检查
Object.getPrototypeOf(yourvariable) === Array.prototype
答案 18 :(得分:5)
如果你知道你的对象没有concat方法,可以使用以下内容。
var arr = [];
if (typeof arr.concat === 'function') {
console.log("It's an array");
}
&#13;
答案 19 :(得分:5)
我见过的最佳解决方案是替代typeof的跨浏览器。检查Angus Croll的解决方案here。
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 */};
答案 20 :(得分:5)
检查对象是否为数组的最简单快捷的方法。
var arr = [];
arr.constructor.name ==='Array' //return true;
或
arr.constructor ===Array //return true;
或者您可以创建实用程序功能:
function isArray(obj){ return obj && obj.constructor ===Array}
用法:
isArray(arr); //return true
答案 21 :(得分:5)
这是我的懒惰方法:
if (Array.prototype.array_ === undefined) {
Array.prototype.array_ = true;
}
// ...
var test = [],
wat = {};
console.log(test.array_ === true); // true
console.log(wat.array_ === true); // false
我知道“弄乱”原型是亵渎神灵,但it appears to perform significantly better than the recommended toString
method。
注意:这种做法的一个陷阱是wont work across iframe
boundaries,但对于我的用例,这不是问题。
答案 22 :(得分:4)
此函数几乎可以将任何内容转换为数组:
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
,因为它是most robust,也是最简单的。
答案 23 :(得分:4)
在您的情况下,您可以使用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
public class MainActivity extends AppCompatActivity {
AutoCompleteTextView machineNameAT;
ArrayList<MachineNameModel> machineNameArrayList;
MachineNameAutoCompleteAdapter machineNameAutoCompleteAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
machineNameArrayList=new ArrayList<>();
machineNameAT = (AutoCompleteTextView)findViewById(R.id.machineNameAT);
machineNameAT.setThreshold(1);
MachineNameModel machineNameModel=new MachineNameModel("1","101","1001","LAPTOP","000.000.000.001");
machineNameArrayList.add(machineNameModel);
MachineNameModel machineNameModel1=new MachineNameModel("2","102","1002","MOBILE","000.000.000.002");
machineNameArrayList.add(machineNameModel1);
MachineNameModel machineNameModel2=new MachineNameModel("3","103","1003","PRINTER","000.000.000.003");
machineNameArrayList.add(machineNameModel2);
machineNameAutoCompleteAdapter = new MachineNameAutoCompleteAdapter(this,R.layout.machine_name_item, machineNameArrayList);
machineNameAT.setAdapter(machineNameAutoCompleteAdapter);
machineNameAutoCompleteAdapter.notifyDataSetChanged();
machineNameAT.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus)
machineNameAT.showDropDown();
}
});
machineNameAT.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
machineNameAT.showDropDown();
return false;
}
});
machineNameAT.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
machineNameAT.showDropDown();
}
@Override
public void afterTextChanged(Editable s) {
if(machineNameArrayList.contains(machineNameAT.getText().toString())){
machineNameAutoCompleteAdapter.notifyDataSetChanged();
machineNameAT.showDropDown();
}else{
MachineNameModel machineNameModel1=new MachineNameModel("","","",machineNameAT.getText().toString(),"");
machineNameArrayList.add(machineNameModel1);
machineNameAutoCompleteAdapter = new MachineNameAutoCompleteAdapter(MainActivity.this,R.layout.machine_name_item, machineNameArrayList);
machineNameAT.setAdapter(machineNameAutoCompleteAdapter);
machineNameAutoCompleteAdapter.notifyDataSetChanged();
machineNameAT.showDropDown();
}
}
});
});
}
}
似乎是Array中最古老的方法之一(即使IE 5.5也很清楚)。
答案 24 :(得分:4)
你可以试试这个:
var arr = []; (or) arr = new Array();
var obj = {}; (or) arr = new Object();
arr.constructor.prototype.hasOwnProperty('push') //true
obj.constructor.prototype.hasOwnProperty('push') // false
答案 25 :(得分:4)
测试输入值是否为数组的简单函数如下:
function isArray(value)
{
return Object.prototype.toString.call(value) === '[object Array]';
}
这适用于跨浏览器和旧版浏览器。这是pulled from T.J. Crowders' blog post
答案 26 :(得分:4)
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))
答案 27 :(得分:4)
A = [1,2,3]
console.log(A.map==[].map)
寻找最短的版本是我到目前为止所得到的。
注意,没有完美的功能可以始终检测所有可能的组合。 了解工具的所有功能和限制比使用魔术工具更好。
答案 28 :(得分:4)
如果可以传递给此函数的唯一两种值是字符串或字符串数组,请保持简单并使用typeof
检查字符串的可能性:
function someFunc(arg) {
var arr = (typeof arg == "string") ? [arg] : arg;
}
答案 29 :(得分:3)
非常感谢,ECMA 5于2009年12月推出了Array.isArray()
。如果由于某种原因,您使用的JavaScript版本早于ECMA 5,请升级。
但是,如果您坚持这样做,那么数组确实具有某些使它们与其他类型区分开的属性。在其他任何答案中都未提及我未看到的属性。让我们进入一些JavaScript政治。
数组是一个对象(typeof [] === "object"
),但与传统对象不同,它们具有length属性(typeof ( {} ).length === "undefined"
)。 null
也是对象(typeof null === "object"
的,但是您不能访问null
的属性,因为null
是 not < / em>对象。这是规范中的错误,可追溯到JavaScript的最开始,当时对象的类型标签为0
,而null
的类型表示为文字空指针0x00
,这导致解释器将其与对象混淆。
不幸的是,这并不代表[]
与{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()
。但出于此目的,通常需要检查对象是否为数组,该对象应与您的代码配合使用。甚至人为地更改数组长度时的行为也相同:如果长度比数组中元素的数量长,您将拥有特殊的“隐式未定义”类型的“空插槽”,该类型与某种程度上与未定义,同时也是=== 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
。
is_array()
但是不要使用public class Proj {
public List dsp(ArrayList<Integer> list) {
return list;
}
public static void main(String[] args) {
int[] nums = {4,3,2,7,8,2,3,1};
List<Integer> bl = new ArrayList<>();
for (int var : nums) {
bl.add(var);
}
Proj p = new Proj();
p.dsp(bl);
System.out.println(bl);
}
}
。为学习目的而重新发明轮子是一回事。在生产代码中这样做是另一回事。甚至不要将其用作polyfill。支持旧版JS意味着支持旧版浏览器意味着鼓励使用不安全的软件,这意味着使用户面临恶意软件的风险。
答案 30 :(得分:2)
最佳做法是使用constructor
进行比较,类似这样
if(some_variable.constructor === Array){
// do something
}
您也可以使用其他方法,例如typeOf
,将其转换为字符串,然后进行比较,但将其与dataType进行比较总是一种更好的方法。
答案 31 :(得分:1)
var is_array = function (value) {
return value &&
typeof value === 'object' &&
typeof value.length === 'number' &&
typeof value.splice === 'function' &&
!(value.propertyIsEnumerable('length'));
};
这个功能取自“JS the good parts”一书,对我来说非常适合。
答案 32 :(得分:1)
还存在其他检查方法,但我更喜欢以下方法 作为我最好的检查(因为您可以轻松检查其他对象的类型)。
> a = [1, 2]
[ 1, 2 ]
>
> Object.prototype.toString.call(a).slice(8,).replace(/\]$/, '')
'Array'
>
> Object.prototype.toString.call([]).slice(8,-1) // best approach
'Array'
说明(有关节点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'
>
空或未定义»
> 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'
>
我感谢@mpen
提出的如下使用-1代替正则表达式的建议。
> 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'
>
答案 33 :(得分:0)
您还可以检查数组的length属性。当您尝试访问数组的length属性时,它将返回一个数字(空数组为0),而如果您尝试访问对象的length属性,则它将返回未定义。
<script>
答案 34 :(得分:0)
// 简单的方法
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));
答案 35 :(得分:0)
Array.isArray(obj),不会给出非常有用的结果。我创建了Object的原型方法,该方法似乎可以正确确定and object是否为数组。
我唯一知道的失败情况是数组中的项目设置为undefined时。
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
答案 36 :(得分:0)
您要检查参数是否为字符串-请尝试
x===x+''
let isStr = x=> x===x+'';
console.log( isStr([]) );
console.log( isStr(["aa","bb"]) );
console.log( isStr("") );
console.log( isStr("abc") );
答案 37 :(得分:0)
var a = [], b = {};
console.log(a.constructor.name == "Array");
console.log(b.constructor.name == "Object");
答案 38 :(得分:0)
尽管有一些可靠的答案,但我更喜欢使用Functor的功能方法。 Functor只是一种奇特的方式,可以说我们将函数传递给值。 (我看到的建议是将值传递给函数)
创建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正在将我们的predicate
和defaultValue
传递给TypeOf
,并且在我们调用/执行ArrayBox
时将可用(命名对您的用例有意义)。
现在有趣的部分
如果输入是数组,则将其返回。
ArrayBox(["foo", "bar"]).value; // ['foo', 'bar']
如果输入不是数组,则将其返回一个
ArrayBox("foo").value // ["foo"]
此方法的优点在于它可以缩放,易于测试并且使用合成。您可以以任何方式组合功能以获得所需的结果。
我们可以使用Eader或Monads来解决此问题。
答案 39 :(得分:0)
首先,您可以检查console.log(对象的类型)
如果输出是对象,则 var {data} = object,即仅根据对象键解构对象。 功能可以是这样的。
const abc=(str1,str2=null)=>{
var result=[];
result.push(str1);result.push(str2);
return result.join("");
}
答案 40 :(得分:0)
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);
答案 41 :(得分:0)
这是一个代码段,它将解释学习JS时应该早知道的数组的重要事实(与我不同)。
// 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
Arrays实际上是对象。
使用typeof运算符,stringInsideArray('hello')
的输出证明["hello"]
是确实个对象。这使我很困惑,因为我认为数组是JavaScript数据类型。
只有7种JS数据类型,并且数组NOT是其中之一。
要回答您的问题,请使用Array.isArray()方法确定output
是一个数组。
答案 42 :(得分:0)
检出它的原型和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
将其视为数组。
答案 43 :(得分:0)
由于我不喜欢任何Object.prototype-calls,我搜索了另一个解决方案。特别是因为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");
有人可以确认这适用于所有情况吗?或者有人发现我的解决方案不起作用的情况吗?
答案 44 :(得分:0)
您可以使用以下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));
答案 45 :(得分:0)
我知道这是一个老问题,但这是我提出的解决方案,并且一直用于我的项目......
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方法更快。
答案 46 :(得分:0)
您可以使用此功能获取数据类型。
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')};
答案 47 :(得分:-1)
我知道这是一个老问题,但我现在找到了最短的答案:
var x = [1,2,3]
console.log(x.map?1:0)
答案 48 :(得分:-1)
这是我使用的:
powershell -STA -File script.ps1
答案 49 :(得分:-4)
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();