วิธีการตรวจสอบว่าวัตถุเป็นอาร์เรย์?


2752

ฉันพยายามเขียนฟังก์ชั่นที่ยอมรับรายการสตริงหรือสตริงเดียว ถ้าเป็นสตริงฉันก็อยากแปลงมันเป็นอาเรย์ที่มีเพียงหนึ่งไอเท็มดังนั้นฉันสามารถวนซ้ำมันได้โดยไม่ต้องกลัวว่าจะเกิดข้อผิดพลาด

ดังนั้นฉันจะตรวจสอบว่าตัวแปรเป็นอาร์เรย์ได้อย่างไร


ผมเคยปัดเศษขึ้นการแก้ปัญหาต่าง ๆ ดังต่อไปนี้และสร้างการทดสอบ jsperf พวกเขากำลังได้อย่างรวดเร็วทั้งหมดดังนั้นเพียงแค่ใช้Array.isArray- เป็นอย่างดีได้รับการสนับสนุนในขณะนี้และการทำงานข้ามเฟรม


6
ฉันคิดว่าคุณหมายถึง 'ตรวจสอบว่าวัตถุเป็นอาร์เรย์' แต่คุณต้องการตรวจสอบว่า 'วัตถุเป็นอาร์เรย์ของสตริงหรือสตริงเดียว' โดยเฉพาะ ไม่แน่ใจว่าคุณเห็นหรือไม่ หรือเป็นแค่ฉันเหรอ? ฉันกำลังคิดถึงสิ่งที่มากกว่านี้ ... ฉันเป็นคนที่ขาดอะไรบางอย่างที่นี่หรือไม่?
rr1g0

149
TL; DR - arr.constructor === Arrayเร็วที่สุด
Neta

3
jsben.ch/#/QgYAV - มาตรฐานสำหรับวิธีที่พบมากที่สุด
EscapeNetscape

39
TL; DR - อาร์เรย์ isArray (arr)ตั้งแต่ ES5; และ $ isArray (arr)ใน jQuery
Ondra Žižka

6
เพียงจำไว้ว่าถ้าคุณเขียนทับ Constructor ของคุณด้วยเหตุผลใดก็ตามarr.constructor === Arrayการทดสอบนั้นจะส่งคืนค่าเท็จ Array.isArray(arr)ยังคงกลับมาจริงแม้ว่า
ghaschel

คำตอบ:


977

ในเบราว์เซอร์สมัยใหม่คุณสามารถทำได้

Array.isArray(obj)

( รองรับโดย 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

9
นี่คือรายการเบราว์เซอร์ที่สมบูรณ์เพิ่มเติมที่รองรับArray.isArray
lightswitch05

if (typeof Array.isArray === 'undefined') {สามารถเปลี่ยนเป็นif(!Array.isArray) {
iMatoria

สำหรับสิ่งที่มีค่าObject.prototype.string.call(obj)สามารถปลอมแปลงได้หากวัตถุมีSymbol.toStringTagอยู่ ที่กล่าวว่าฉันไม่ได้ตระหนักถึงสภาพแวดล้อมใด ๆ ที่จัดส่งSymbol.toStringTagแต่ไม่Array.isArrayเช่นนั้นดูเหมือนปลอดภัย
Benjamin Gruenbaum

5
เหตุใดจึงinstanceof Arrayล้มเหลวหากอาร์เรย์มาจากเฟรมอื่น
NobleUplift

16
@NobleUplift: instanceof Arrayล้มเหลวหากอาร์เรย์มาจากเฟรมที่แตกต่างกันเนื่องจากทุกอาร์เรย์จากเฟรมที่แตกต่างนั้นมีคอนArrayสตรัคเตอร์และต้นแบบที่แตกต่างกัน เพื่อเหตุผลด้านความเข้ากันได้ / ความปลอดภัยทุกเฟรมมีสภาพแวดล้อมแบบโกลบอลของตัวเอง Objectระดับโลกจากหนึ่งเฟรมจะแตกต่างจากObjectทั่วโลกจากที่อื่น ดังนั้นสำหรับArrayกลม Axel Rauschmayer พูดถึงเรื่องนี้มากขึ้น
jschoi

1943

วิธีการที่กำหนดในมาตรฐาน ECMAScript เพื่อหาระดับของวัตถุคือการใช้วิธีการจากtoStringObject.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']

65
+1 Yup toStringเป็นหนึ่งในวิธีที่จะไป ฉันทำบทสรุปเล็กน้อยที่นี่: blog.niftysnippets.org/2010/09/say-what.html
TJ Crowder

3
typeof new String('beans') > 'object'
Ben

16
หากคุณไม่ต้องการพิมพ์ "[object Array]" ให้ใช้ Object.prototype.toString.call (someVar) === Object.prototype.toString.call ([]) หรือทำให้ฟังก์ชั่นอำนวยความสะดวกในการพิมพ์ถ้าคุณไม่ต้องการ ไม่ต้องการพิมพ์ Object.prototype.toString.call
Pramod

13
ฉันใช้ vanilla Array.isArray ซึ่งทำงานใน 'เบราว์เซอร์สมัยใหม่' (นั่นคือ IE9 + และทุกคน) และสำหรับการรองรับเบราว์เซอร์เก่าให้ใช้ shim จาก MDN developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
David Gilbertson

21
อาศัยอยู่ในโลกสมัยใหม่ -Array.isArray(obj)
mcfedr

1274

ฉันจะตรวจสอบก่อนว่าการใช้งานของคุณรองรับisArray:

if (Array.isArray)
    return Array.isArray(v);

คุณสามารถลองใช้instanceofโอเปอเรเตอร์ได้

v instanceof Array

127
v instanceof Arrayจะส่งกลับค่า false หากvสร้างขึ้นในอีกเฟรมหนึ่ง ( vเป็นอินสแตนซ์ของthatFrame.contentWindow.Arrayคลาส)
pepkin88

47
To specific: Array.isArrayถูกกำหนดเป็นส่วนหนึ่งของ ECMAScript 5 / Javascript 1.8.5
jevon

8
โซลูชันที่เรียบง่ายและเรียบร้อยจริงๆ แต่ isArray ไม่สามารถใช้งานร่วมกับเบราว์เซอร์รุ่นเก่า (เช่น IE7 และ IE8) ที่มา: kangax.github.io/es5-compat-table/#
Wookie88

2
แล้วถ้า: (Array.isArray) คืน Array.isArray (v); อื่นกลับ v instanceof ของอาร์เรย์;
lewdev

1
หรือเพียงแค่:return (Array.isArray && Array.isArray(v)) || (v instanceof Array);
Stijn de Witt

298

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>


27
เพิ่งทราบว่า jQuery ใช้วิธีการ toString ภายใน: แหล่งที่มาของ GitHub
Jacob Squires

5
@JacobSquires มันขึ้นอยู่กับ ฉันเพิ่งทดสอบที่นี่ jQuery ล่าสุดบน Chrome - $.isArray === Array.isArrayกลับมาเป็นจริง
Renan

3
@ Renan: นี่คือสิ่งที่ดีเกี่ยวกับการใช้ jQuery โดยปกติจะใช้วิธีการที่ทันสมัยที่สุดและดีที่สุดในการทำเช่นนั้นและคุณไม่จำเป็นต้องตรวจสอบคุณสมบัติทั้งหมดด้วยตัวเองเพื่อใช้งาน
ความกลัว

jQuery กำลังใช้งาน Array.isArrayเบื้องหลัง: github.com/jquery/jquery/blob/master/src/core.js#L211
Sergiu

1
แต่จะไม่มีใครใช้ jQuery เพียงแค่สำหรับการทำงานนี้ใช่ไหม? ฉันจะไม่ดาวน์โหลด jquery เพียงเพราะต้องการตรวจสอบว่ามีอาร์เรย์หรือไม่: p
Automagisch

106

นี่เป็นวิธีที่เร็วที่สุดในทุกวิธี (เบราว์เซอร์ทั้งหมดที่รองรับ):

function isArray(obj){
    return !!obj && obj.constructor === Array;
}

2
คุณพูดถูกนั่นเป็นวิธีที่เร็วที่สุดตามแบบทดสอบที่ฉันรวมไว้ในคำถาม
mpen

5
มีข้อเสียในการใช้วิธีนี้หรือไม่? ดูเหมือนง่ายและมีประสิทธิภาพมากกว่าคำตอบที่ได้รับการยอมรับ
David Meza

@shinobi - เพียงแค่อยากรู้อยากเห็น (และฉันได้เห็นสิ่งนี้บ่อยครั้ง) - ทำไมคุณถึงพูดถึงเงื่อนไขif (obj && Array === obj.constructor)ที่ต่างไปif (obj && obj.constructor === Array)? มันหายไปในการแปลเป็นภาษาอังกฤษแล้วรหัสสิ่ง? เช่นโดยทั่วไปผู้พูดภาษาอังกฤษมักจะถามว่า "มีวัตถุอยู่หรือไม่และตัวสร้างมาจากคลาสอาเรย์หรือไม่" ดังนั้นการไหลของรหัสเมื่ออ่านจะมีเหตุผลมากกว่า หรือมีเหตุผลทางเทคนิคบ้าง
ไนซ์

function object_type(o){var t = typeof(o);return ((t==="object") && (o.constructor===Array)) ? "array" : t;} /*allows you to */ switch(object_type(o)){ case 'array': break; case 'object' : o.dosomething();}
ไนซ์

3
@ shinobi ดีทั้งหมด ฉันคิดว่ามันอาจจะเป็นอาการเมาค้างจากนิสัยปลอดภัย - ถ้าคุณตั้งใจใช้ = แทน == มันจะไม่รวบรวมเพราะไม่ใช่ตัวแปรที่กำหนดได้
ไนซ์

47

ลองนึกภาพคุณมีอาร์เรย์ด้านล่างนี้ :

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);

34

Array.isArray ทำงานได้อย่างรวดเร็ว แต่เบราว์เซอร์ทุกรุ่นไม่รองรับ ดังนั้นคุณสามารถยกเว้นสำหรับผู้อื่นและใช้วิธีการแบบสากล:

    Utils = {};    
    Utils.isArray = ('isArray' in Array) ? 
        Array.isArray : 
        function (value) {
            return Object.prototype.toString.call(value) === '[object Array]';
        }

3
คุณจำเป็นต้องได้รับวิธีการจาก.toString() Object.prototypeตอนนี้คุณกำลังใช้window.toString()ซึ่งไม่เหมือนกัน
ระบบ

คุณพูดถูก window.toStringทำเช่นเดียวกับObject.prototype.toStringใน Chrome
CruorVult

isArray นั้นไม่เร็วเลย มันเป็นวิธีที่ช้าที่สุด
jemiloii

ทำไมไม่เพียงเพิ่มเข้าไปใน Array แทนที่จะใช้ Utils (ฉันรู้ว่าคุณไม่ต้องการคุณสมบัติพิเศษสำหรับวัตถุอาร์เรย์ใหม่ แต่ฉันคิดว่าจะเกิดขึ้นเฉพาะเมื่อคุณเพิ่ม isArray ไปยัง Array.prototype)
David Winiecki

27

ฟังก์ชั่นง่าย ๆ เพื่อตรวจสอบสิ่งนี้:

function isArray(object)
{
    return object.constructor === Array;
}

16
ฉันจะลดมันลงไปที่หนึ่งบรรทัดreturn object.constructor === Array- แต่คุณแน่ใจหรือไม่ว่าสิ่งนี้จะส่งกลับค่าจริงสำหรับอาร์เรย์เท่านั้น
mpen

12
สามารถทำได้ด้วยการแสดงออกแบบบูลทั้งหมด ผลักดันฉันถั่วเมื่อฉันเห็นif(x) return true; else return false:-) แม้ว่าจะถอยหลังคุณควรลบล้างการแสดงออก
mpen

3
เหตุผลที่สิ่งนี้ไม่ส่งคืนค่าจริงสำหรับ getElementsByTagName เนื่องจากผลลัพธ์ของฟังก์ชันนั้นเป็น HTMLCollection จริง ๆ และไม่ใช่อาร์เรย์
Yuval A.

6
สิ่งนี้ล้มเหลวอย่างรุนแรงหากวัตถุไม่ได้กำหนดหรือเป็นโมฆะ
John Henckel

1
@JohnHenckel ดูคำตอบของฉันstackoverflow.com/a/29400289/34806มันคำนึงถึงทั้งความกังวลของคุณและความคิดเห็นแรกทั้งหมดในบรรทัดเดียว
Dexygen

17

อย่างที่ MDN บอกไว้ที่นี่ :

ใช้Array.isArrayหรือObject.prototype.toString.callเพื่อแยกแยะวัตถุปกติจากอาร์เรย์

แบบนี้:

  • Object.prototype.toString.call(arr) === '[object Array]', หรือ

  • Array.isArray(arr)


17

มีวิธีแก้ปัญหาหนึ่งบรรทัดสำหรับคำถามนี้

x instanceof Array

โดยที่ x คือตัวแปรมันจะคืนค่าจริงถ้า x เป็นอาร์เรย์และเท็จถ้าไม่ใช่


ปลอดภัยมากขึ้นและปลอดภัยในอนาคต! นี่หรือการtypeofเปรียบเทียบ
ChristoKiwi

นี่เป็นสิ่งที่ได้รับการสนับสนุนเบราว์เซอร์ในปริมาณที่ดีหรือไม่? ฉันชอบมัน.
Dan Zuzevich

1
น่าเสียดายที่นี่ไม่มีประโยชน์จริง ๆ หากไม่ลอง / จับเพราะถ้า "x" เป็นวัตถุเช่น{}อาร์เรย์คุณจะได้รับข้อผิดพลาดทางไวยากรณ์
หยุดยั้ง

15

คุณสามารถตรวจสอบประเภทของตัวแปรของคุณไม่ว่าจะเป็นอาเรย์ด้วย

var myArray=[];

if(myArray instanceof Array)
{
....
}

1
มีบางคนพูดถึงแล้วinstanceof.. ฉันคิดว่ามันล้มเหลวภายใต้สถานการณ์แปลก ๆ
mpen

15

ฉันจะสร้างฟังก์ชั่นเพื่อทดสอบประเภทของวัตถุที่คุณติดต่อด้วย ...

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(whatAmI(myVar) === "Array"){
    // do array stuff
} else { // could also check `if(whatAmI(myVar) === "String")` here to be sure
    // do string stuff
}

12

ฉันทำสิ่งนี้ในวิธีที่ง่ายมาก ได้ผลสำหรับฉัน ข้อเสียใด ๆ

Array.prototype.isArray = true;

a=[]; b={};
a.isArray  // true
b.isArray  // (undefined -> false)

7
ถูกหลอกโดย{isArray:true}
Bergi

JSON.parse(someDataFromElsewhere).items.isArrayสามารถส่งคืนจริง (ขึ้นอยู่กับข้อมูล) และทำลายรหัสของคุณ
Roy Tinker

12

นี่คือความพยายามของฉันในการปรับปรุงคำตอบนี้โดยคำนึงถึงความคิดเห็น:

var isArray = myArray && myArray.constructor === Array;

มันจะกำจัด if / else และบัญชีสำหรับความเป็นไปได้ของอาร์เรย์ที่เป็นโมฆะหรือไม่ได้กำหนด


ตัวสร้างไม่พร้อมใช้งานใน ES5
TechTurtle


11

ฉันได้อัพเดทซอ 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/>");

วิธีการทั้งสองนี้ใช้ไม่ได้หากตัวแปรใช้ค่าที่ไม่ได้กำหนด แต่จะทำงานหากคุณมั่นใจว่าพวกเขามีค่า สำหรับการตรวจสอบโดยคำนึงถึงประสิทธิภาพว่าค่าเป็นอาร์เรย์หรือค่าเดียววิธีที่สองจะดูเหมือนวิธีรวดเร็วที่ถูกต้อง มันเร็วกว่า 'instanceof' บน Chrome เล็กน้อยเร็วเป็นสองเท่าของวิธีที่ดีที่สุดอันดับสองใน Internet Explorer, Opera และ Safari (บนเครื่องของฉัน)


9

ฉันรู้ว่าคนกำลังมองหาวิธีการจาวาสคริปต์ดิบบางชนิด แต่ถ้าคุณต้องการคิดให้น้อยลงลองดูที่นี่: http://underscorejs.org/#isArray

_.isArray(object) 

ผลตอบแทนจริงถ้าวัตถุเป็นแบบอาร์เรย์

(function(){ return _.isArray(arguments); })();
=> false
_.isArray([1,2,3]);
=> true

7
"นอกจากจะรวมแท็กอื่นสำหรับเฟรมเวิร์ก / ไลบรารีแล้วคาดว่าจะได้คำตอบของ JavaScript อย่างแท้จริง"
MichałPerłakowski

5

ทางออกที่ดีที่สุดที่ฉันเคยเห็นคือการแทนที่ข้ามเบราว์เซอร์สำหรับประเภทของ ตรวจสอบวิธีการแก้ปัญหาของ Angus Croll ที่นี่ที่นี่

รุ่น 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 */};

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

ฉันรู้ว่ามันเป็นสิ่งศักดิ์สิทธิ์ที่จะ "ยุ่งกับ" ต้นแบบ แต่ดูเหมือนว่าจะทำงานได้ดีกว่าtoStringวิธีที่แนะนำวิธีการ

หมายเหตุ:ข้อผิดพลาดของวิธีนี้คือมันไม่สามารถทำงานข้ามiframeขอบเขตได้ แต่สำหรับกรณีการใช้งานของฉันนี่ไม่ใช่ปัญหา


มันไม่ได้ดีขึ้นในแง่ของประสิทธิภาพอีกต่อไปอย่างน้อยใน FF30 บน Ubuntu 64-bit
test30

2
ถูกหลอกโดยwat = {array_: true}วัตถุ
Bergi

@Bergi: ใช่ว่าควรจะชัดเจน หากคุณกำลังตั้งค่าobj.array_ = trueคุณจะหลอกตัวเองเท่านั้น
namuol

@namuol: ฉันไม่จำเป็นต้องหลอกตัวเอง บ่อยครั้งที่มีการใช้วัตถุมากพอเป็นพจนานุกรม นึกถึงcacheวัตถุที่จะบันทึกผลลัพธ์การค้นหาซึ่งใช้สตริงการค้นหาเป็นคีย์คุณสมบัติ เกิดอะไรขึ้นถ้าผู้ใช้ค้นหาarray_? วัตถุของคุณกลายเป็นอาร์เรย์เพราะสิ่งนั้นหรือไม่? มันเป็นเพียงข้อบกพร่อง
Bergi

@namuol: นอกจากนี้วิธีการนี้จะกำหนดให้ทุกฝ่ายที่เกี่ยวข้อง (รวมถึงห้องสมุดที่ใช้) สามารถยอมรับว่า.array_ใช้สำหรับการติดแท็กอาร์เรย์ นั่นไม่ใช่กรณีที่นี่จริงๆ.arrayอาจหมายถึงอะไร .__isArray = trueอย่างน้อยคุณควรใช้สตริงพรรณนาและความไม่เหมาะสมในการใช้สัญญาณโดยพลการเช่นกับ
Bergi

5

มีตัวอย่างที่ดีในรูปแบบ JavaScriptของหนังสือ Stoyan Stefanov ซึ่งคาดว่าจะจัดการกับปัญหาที่เป็นไปได้ทั้งหมดรวมถึงใช้วิธี ECMAScript 5 Array.isArray ()()

ดังนั้นนี่คือ:

if (typeof Array.isArray === "undefined") {
    Array.isArray = function (arg) {
        return Object.prototype.toString.call(arg) === "[object Array]";
    };
}

โดยวิธีการถ้าคุณใช้ jQuery คุณสามารถใช้มันเป็นวิธี$ .isArray ()


2
+1: ทำไมไม่ง่ายอย่างนั้นif(!Array.isArray) {...ล่ะ
Marco Demaio

5

วิธีที่ง่ายที่สุดและเร็วที่สุดในการตรวจสอบว่า Object เป็น Array หรือไม่

 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

5

คุณสามารถใช้วิธีการต่อไปนี้หากคุณรู้ว่าวัตถุของคุณไม่มีวิธีการเชื่อมต่อ

var arr = [];
if (typeof arr.concat === 'function') {
    console.log("It's an array");
}


นี่เป็นเคล็ดลับที่ดี แต่อาจถูกแทนที่ ... แต่ส่วนใหญ่ควรได้ผลลัพธ์
Alireza

5

คุณสามารถเป็นวิธี isArray แต่ฉันต้องการตรวจสอบด้วย

Object.getPrototypeOf(yourvariable) === Array.prototype


ทำไมคุณถึงชอบสิ่งนี้
mpen

@mpen Object.getPrototypeOf(yourvariable)มันจะคืนค่าต้นแบบของวัตถุ Array และรหัสนั้นเร็วและปลอดภัยต่อการพึ่งพา
STEEL

1
เป็นเรื่องง่ายที่จะทำลาย: pastebin.com/MP8d5bCEนอกจากนี้คุณมีการทดสอบประสิทธิภาพเพื่อสำรองข้อมูลการเรียกร้อง "เร็วที่สุด" ของคุณหรือไม่?
mpen

4

หากมีเพียงสองประเภทของค่าที่สามารถส่งผ่านไปยังฟังก์ชันนี้เป็นสตริงหรืออาร์เรย์ของสตริงให้ใช้งานง่ายและใช้การtypeofตรวจสอบความเป็นไปได้ของสตริง:

function someFunc(arg) {
    var arr = (typeof arg == "string") ? [arg] : arg;
}

ใช่ ... นั่นจะใช้ได้กับสถานการณ์นี้ แต่ไม่ใช่โดยทั่วไป ลงเอยด้วยการใช้ varargs อยู่ดี :)
mpen

4
A = [1,2,3]
console.log(A.map==[].map)

ในการค้นหาเวอร์ชั่นที่สั้นที่สุดนี่คือสิ่งที่ฉันได้รับ

หมายเหตุไม่มีฟังก์ชั่นที่สมบูรณ์แบบที่จะตรวจจับชุดค่าผสมที่เป็นไปได้ทั้งหมด เป็นการดีกว่าที่จะรู้ความสามารถและข้อ จำกัด ทั้งหมดของเครื่องมือของคุณดีกว่าที่คาดว่าเป็นเครื่องมือวิเศษ


1
การขุดเล็กน้อยของฉันA.map !== undefinedแต่ใช่นั่นอาจเป็นถนนที่ลื่นในโลกของนัก
ปะติด

FYI: วิธีนี้ใช้ไม่ได้กับ iFrames ( stackoverflow.com/questions/460256/… )
WiredPrairie

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))

4

ฟังก์ชั่นที่ง่ายสำหรับการทดสอบว่าค่าอินพุตเป็นอาร์เรย์มีดังต่อไปนี้:

function isArray(value)
{
  return Object.prototype.toString.call(value) === '[object Array]';
}

สิ่งนี้ใช้ได้กับเบราว์เซอร์ข้ามและกับเบราว์เซอร์รุ่นเก่า สิ่งนี้ดึงมาจากการโพสต์บล็อกของ TJ Crowders


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

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' ]

สตริง NB จะถูกแปลงเป็นอาร์เรย์ที่มีองค์ประกอบเดียวแทนอาร์เรย์ของตัวอักษร ลบเครื่องหมายisStringตรวจสอบถ้าคุณต้องการวิธีอื่น ๆ

ฉันใช้Array.isArrayที่นี่เพราะมันแข็งแกร่งและเรียบง่ายที่สุด


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 ดูเหมือนว่าจะเป็นหนึ่งในวิธีที่เก่าแก่ที่สุดของ Array (แม้แต่ IE 5.5 ก็รู้ดี)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.