Làm cách nào để kiểm tra loại mảng trong JavaScript?

Mảng JavaScript là một loại đối tượng, vì vậy, typeof [] trả về "object" — không hữu ích lắm nếu bạn có một mảng. Dưới đây là 5 phương pháp để kiểm tra xem một đối tượng JavaScript có phải là một mảng hay không

Show
Ảnh của JJ Ying trên Bapt

Một vấn đề phổ biến trong xác thực dữ liệu JavaScript là kiểm tra xem một biến đã cho có chứa một mảng hay không

“Mảng là các đối tượng giống như danh sách có nguyên mẫu có các phương thức để thực hiện các thao tác duyệt và đột biến. ” — Tài liệu MDN

Đối với các kiểu nguyên thủy, từ khóa typeof thường hoạt động khá tốt, nhưng mảng typeof an là "object". typeof [] === object // true

Mặc dù điều đó có ý nghĩa (xét cho cùng, mảng là một loại đối tượng JavaScript tích hợp sẵn), nhưng nó không hữu ích để phân biệt mảng với các đối tượng khác

Ngoài ra, nhận được "object" từ typeof có thể biểu thị giá trị Object.prototype.toString.call([])0

Rất may, có nhiều cách để kiểm tra một mảng JavaScript

  • Cách 1) Array.isArray([])
  • Cách 2) Object.prototype.toString.call([])
  • Phương pháp 3) Object.prototype.toString.call([])3
  • Phương pháp 4) Object.prototype.toString.call([])4
  • Phương pháp 5) Object.prototype.toString.call([])5 với Object.prototype.toString.call([])4

Trong bài viết này, tôi sẽ giải thích những ưu và nhược điểm của từng phương pháp

Phương pháp 1. Array.isArray([])

ECMAScript 5 (ES5) đã giới thiệu phương pháp Object.prototype.toString.call([])8 để kiểm tra một mảng, vì typeof sẽ không thể phân biệt mảng với các đối tượng khác, chẳng hạn như các đối tượng tích hợp sẵn typeof []0 và typeof []1

Sử dụng typeof []2 cũng hữu ích để đảm bảo rằng đối tượng của chúng ta không phải là typeof []3, vì Object.prototype.toString.call([])0 có typeof []5 do một lỗi đã tồn tại từ lâu

Đây là một ví dụ về việc kiểm tra một mảng bằng cách sử dụng Array.isArray([])

Xem mã thô dưới dạng GitHub Gist

Phương pháp 2. ________số 8_______

Câu lệnh JavaScript dài dòng typeof []8 có thể phân biệt giữa mảng và các loại đối tượng khác, bởi vì nó trả về một chuỗi xác định loại đối tượng chi tiết hơn so với typeof

Bởi vì phương pháp này sẽ hoạt động với bất kỳ đối tượng nào, tôi gọi nó là cách tốt nhất để gõ kiểm tra trong JavaScript. Đây là một ví dụ

Xem mã thô dưới dạng GitHub Gist

Trong khi dài dòng, phương thức này sẽ hoạt động với bất kỳ kiểu nguyên thủy nào và cho bất kỳ đối tượng nào. Nó luôn trả về tên của hàm tạo cho biến

Nói cách khác, "object"0 gần giống như "object"1 ngược lại, mặc dù nó hoạt động tốt bên trong "object"2

Hành vi của hàm "object"3 ở trên phải giống hệt với hàm typeof []2 tích hợp

Một điều cần lưu ý ở đây là "object"5 trả về "object" (chữ thường), nhưng "object"7 trả về "object"8 (chữ hoa) cho một đối tượng "object"9 và typeof0 (chữ hoa) cho một mảng typeof1

Như với tất cả các phương thức này, phương thức này sẽ không hoạt động nếu biến chưa được khai báo. Tôi sẽ giải quyết việc kiểm tra các biến không được khai báo sau

Phương pháp 3. Object.prototype.toString.call([])3

Sử dụng từ khóa typeof3 có thể được sử dụng để kiểm tra mảng hoặc bất kỳ loại đối tượng JavaScript nào

“Toán tử typeof4 kiểm tra xem liệu thuộc tính typeof5 của hàm tạo có xuất hiện ở bất kỳ đâu trong chuỗi nguyên mẫu của một đối tượng hay không. ” — Tài liệu MDN

Cú pháp rất đơn giản, như được hiển thị trong ví dụ mã này

Xem mã thô dưới dạng GitHub Gist

Mặc dù vậy, hãy coi chừng, typeof6 có thể vi phạm hành vi này, như được giải thích trong tài liệu Mạng nhà phát triển Mozilla cho typeof7

"object"1 đấu với typeof9

Khi kiểm tra [một] phiên bản typeof0, typeof1 được ưu tiên hơn "object"1 vì nó hoạt động thông qua "object"2. — Tài liệu MDN

Điều đó có nghĩa là chúng tôi có thể không muốn sử dụng "object"1 để kiểm tra một mảng, chỉ trong trường hợp mã JavaScript của chúng tôi chạy bên trong một typeof5

Phương pháp 4. Object.prototype.toString.call([])4

Để cho đầy đủ, tôi muốn đề cập đến một phương thức tương tự như "object"1— gọi thuộc tính typeof8 của một đối tượng JavaScript

Thuộc tính typeof9 sẽ trả về hàm khởi tạo, đối với một mảng sẽ là hàm "object"0 (i. e. lớp JavaScript "object"1)

Truy cập thuộc tính "object"2 của hàm đó sẽ cho chuỗi typeof0, có thể được sử dụng để tạo thành một kiểm tra đơn giản cho sự hiện diện của một mảng

Kể từ khi tài sản typeof9 trả về "object"0 (i. e. lớp JavaScript "object"1), bạn cũng có thể so sánh nó trực tiếp với đối tượng Array toàn cầu (là đối tượng được tham chiếu bởi giá trị trả về "object"0)

Nói cách khác, bạn không thực sự phải sử dụng thuộc tính "object"2;

Đây là một ví dụ mã

Xem mã thô dưới dạng GitHub Gist

Tương tự như "object"0, việc truy cập thuộc tính typeof9 sẽ hoạt động với bất kỳ loại giá trị JavaScript nào, bao gồm cả giá trị nguyên thủy — mặc dù bạn không thể truy cập typeof9 cho các giá trị typeof [] === object // true4 hoặc ________0____3

(Lưu ý rằng từ khóa "object"1 sẽ hoạt động đối với các đối tượng, nhưng không hoạt động đối với các đối tượng nguyên thủy. Và, tất nhiên, "object"1 bị lỗi trong "object"2. )

Như chúng ta thấy ở trên, việc sử dụng typeof9 mà không có dấu kiểm tra typeof []3 sẽ dẫn đến kết quả là "object"1 cho cả typeof []3 và "object"3 — một nhược điểm so với typeof []2, sẽ chỉ trả về "object"5 cho hai giá trị đó

Và, như với bất kỳ phương pháp nào được đề cập cho đến nay, các biến không được khai báo sẽ tạo ra một kết quả "object"6 nếu bạn cố gắng truy cập chúng.

Một lời cảnh báo. typeof9 có thể thay đổi

Trước khi tiếp tục, cần lưu ý rằng typeof9 không mạnh, vì nó là một thuộc tính đối tượng có thể bị ghi đè sau này

“Hãy nhớ rằng nếu vì lý do nào đó bạn ghi đè hàm tạo của mình qua nguyên mẫu thì bài kiểm tra "object"9 sẽ trả về false. typeof0 vẫn trả về true mặc dù. ” – ghaschel

Vì vậy, chỉ cần nhớ rằng thuộc tính typeof9 của một đối tượng là "có thể thay đổi" - nó có thể đã được thay đổi ở đâu đó trong mã so với giá trị ban đầu của nó

Phương pháp 5. && và Object.prototype.toString.call([])4 (_______0_______3 kiểm tra. 😄)

Đây là một lớp lót gọn gàng sẽ kiểm tra giá trị không phải ____0_______3 cùng lúc với việc bạn kiểm tra một mảng. typeof5

Cả typeof []3 và "object"3 đều là giá trị sai, nghĩa là chúng đánh giá sai trong các câu lệnh có điều kiện, nhưng tất cả các đối tượng đều là giá trị trung thực, kể cả các mảng trống. Kiểm tra typeof5 sẽ trả về false cho các giá trị typeof []3 hoặc "object"3, trong khi chỉ riêng typeof9 sẽ gây ra lỗi

Bao gồm Object.prototype.toString.call([])02 có lợi thế là tránh được Object.prototype.toString.call([])03 xảy ra vì typeof []3 và "object"3 không có thuộc tính. Điều này hoạt động vì Object.prototype.toString.call([])5 là một “. ” Bằng cách sử dụng logic AND (Object.prototype.toString.call([])5), chúng tôi kiểm tra xem giá trị có đúng không trước khi thử truy cập thuộc tính typeof9. Đây là một ví dụ mã

Xem mã thô dưới dạng GitHub Gist

Để cải thiện khả năng đọc mã, bạn có thể xem xét thực hiện kiểm tra null rõ ràng bằng cách sử dụng đẳng thức lỏng lẻo. Object.prototype.toString.call([])09. Sử dụng Object.prototype.toString.call([])10 (toán tử bình đẳng lỏng lẻo) có nghĩa là typeof []3 và "object"3 bằng nhau

Một kiểm tra rõ ràng hơn sẽ sử dụng bình đẳng nghiêm ngặt. Object.prototype.toString.call([])13. Nhiều lập trình viên JavaScript không bao giờ muốn sử dụng đẳng thức lỏng lẻo, vì các quy tắc cho Object.prototype.toString.call([])14 rất khó hiểu

Sử dụng Object.prototype.toString.call([])5 với typeof9 hoạt động hiệu quả theo cách tương tự đối với typeof []3 và "object"3 giống như typeof []2. nó trả về false, như bạn mong muốn

Tuy nhiên, các biến không được khai báo sẽ vẫn tạo ra một kết quả "object"6 khi cố gắng truy cập thuộc tính typeof9. Bạn có thể sử dụng typeof để kiểm tra xem giá trị không phải là Object.prototype.toString.call([])23 trước khi kiểm tra mảng để giải quyết vấn đề đó

Nếu biến mảng thực sự không được khai báo thì sao?

Bạn có thể không chắc biến có thể là một mảng đã thực sự được khai báo chưa. Hãy để tôi nói ngắn gọn về việc kiểm tra các mảng không được khai báo

Xin nhắc lại, truy cập vào một biến chưa được khai báo sẽ tạo ra một giá trị Object.prototype.toString.call([])24, trong khi một biến đã được khai báo nhưng không được gán một giá trị cụ thể sẽ có giá trị là typeof [] === object // true4

Rất may, từ khóa typeof sẽ trả về Object.prototype.toString.call([])23 cho một biến chưa được khai báo, giống như nó sẽ trả về giá trị "object"3, nhưng không đưa ra một biến Object.prototype.toString.call([])29 vì biến đó chưa được khai báo

Điều đó có nghĩa là chúng ta có thể bọc typeof []2 bên trong lệnh gọi typeof để làm cho nó mạnh mẽ trước các biến không được khai báo. Đây là một ví dụ

Xem mã thô dưới dạng GitHub Gist

Ngoài ra, chúng ta có thể sử dụng khối Object.prototype.toString.call([])32, nắm bắt được tiềm năng của Object.prototype.toString.call([])29, nhưng typeof cũng hoạt động tốt đối với các biến không được khai báo

Làm cách nào để kiểm tra một mảng trống trong JavaScript?

Thay vào đó, nếu chúng ta muốn kiểm tra xem liệu một mảng có thể trống hay không, chúng ta có thể kiểm tra thuộc tính Object.prototype.toString.call([])35 của nó — một mảng trống có Object.prototype.toString.call([])36 của Object.prototype.toString.call([])37

Một lần nữa, chúng ta cần chắc chắn rằng chúng ta đang làm việc với một biến được khai báo đã được gán một giá trị chắc chắn là một mảng

Nhưng, giả sử chúng ta có Object.prototype.toString.call([])38 từ Array.isArray([]), thì Object.prototype.toString.call([])40 sẽ xác nhận rằng mảng của chúng ta không trống. Đây là một đoạn mã

Xem mã thô dưới dạng GitHub Gist

Một lần nữa, chúng tôi đang tận dụng lợi thế của Object.prototype.toString.call([])5 với tư cách là người điều hành đoản mạch. Bởi vì nó "đoản mạch" trên các câu lệnh sai, chúng ta không bao giờ đạt được lệnh gọi Object.prototype.toString.call([])36 trong ví dụ trên. Đó chính xác là những gì chúng tôi muốn, bởi vì Object.prototype.toString.call([])36 sẽ không hoạt động trên hầu hết các đối tượng nguyên thủy như số hoặc các loại đối tượng khác

Kiểm tra năng suất. Cách nhanh nhất để kiểm tra một mảng trong JavaScript là gì?

Nhà phát triển Mark Penner (mpen) đã sử dụng jsPerf để so sánh các phương pháp kiểm tra mảng khác nhau trong JavaScript

Kết quả của ông cho thấy rằng một phương pháp phổ biến chậm hơn 20% so với các phương pháp khác — mặc dù sự khác biệt là không đáng kể vì kết quả quá nhanh

Đây là những gì tôi nhận được khi chạy bộ thử nghiệm jsPerf của anh ấy vài tháng trước

Các kết quả kiểm tra jsPerf này cho thấy rằng Đối tượng. nguyên mẫu. toString. call([]) chậm hơn khoảng 20% ​​so với các phương thức khác, chẳng hạn như Array. isArray()

(Lưu ý của tác giả. jsPerf hiện đang ngừng hoạt động để chờ một số cấu hình khởi chạy lại. Tôi hy vọng các tác giả làm cho nó hoạt động trở lại. 🙏)

Tóm tắt là typeof []2 nhanh bằng typeof9 hoặc "object"1, nhưng Object.prototype.toString.call([]) chậm hơn

Kết quả hỗ trợ sử dụng typeof []2 theo mặc định, mặc dù sở thích cá nhân của bạn có thể sử dụng typeof9 với dấu kiểm typeof []3

Nhưng nếu bạn là người hâm mộ của Object.prototype.toString.call([]) - đừng lo lắng. Sự khác biệt cho thấy phương pháp chậm hơn một chút này vẫn rất nhanh. hơn 700.000.000 thao tác mỗi giây trên PC tại nhà của tôi

Vì vậy, trừ khi bạn đang thực hiện hàng nghìn tỷ lần kiểm tra mảng, bạn sẽ không thấy sự khác biệt đáng kể về tốc độ mã của mình bằng cách hoán đổi bất kỳ phương thức này sang phương thức khác

Phần kết luận. Cách kiểm tra một mảng JavaScript

Bởi vì từ khóa typeof trả về "object" cho typeof []3 và tất cả các đối tượng — bao gồm cả mảng — việc kiểm tra mảng cần một công cụ khác

Các phương thức dành riêng cho mảng

Phương thức trợ giúp ES5 typeof []2 sẽ nhanh chóng và đơn giản cho bạn biết liệu có bất kỳ biến JavaScript nào là một mảng hay không. Object.prototype.toString.call([])56 và nó hoạt động cho typeof []3 và "object"3 (nhưng không phải là biến không được khai báo)

Phương pháp typeof []2 đó là, kể từ Internet Explorer 9, vì nó là một phần của đặc tả ECMAScript 5

Bạn có thể thấy "object"1 được sử dụng. Object.prototype.toString.call([])61, nhưng "object"1 không được khuyến nghị vì nó không hoạt động bên trong "object"2

Các phương thức hoạt động cho bất kỳ đối tượng nào

Có một số phương pháp hữu ích để kiểm tra mảng vì chúng có thể được sử dụng để xác định loại của bất kỳ đối tượng JavaScript nào

Phương thức tổng quát hơn Object.prototype.toString.call([])64 sẽ cho bạn biết bất kỳ giá trị nào thuộc loại đối tượng nào, bao gồm cả giá trị nguyên thủy

Để chỉ nắm bắt loại, chuỗi đó có thể được xử lý bằng Object.prototype.toString.call([])65. Object.prototype.toString.call([])66

Tương tự, thuộc tính typeof9 sẽ trả về hàm xây dựng của một giá trị JavaScript. Đối với mảng, đây là biến toàn cầu được tích hợp sẵn "object"0

Hàm đó có thể được so sánh với đối tượng toàn cục (i. e. typeof0) hoặc thuộc tính "object"2 của hàm tạo có thể được truy cập dưới dạng một chuỗi. Object.prototype.toString.call([])71

Tuy nhiên, typeof9 có nhược điểm là bạn có thể gán một giá trị mới cho nó, do đó phủ nhận việc kiểm tra mảng của bạn. Object.prototype.toString.call([])73

Kiểm tra các mảng không được khai báo

Từ khóa typeof sẽ không phân biệt mảng với các đối tượng khác, mặc dù typeof vẫn hữu ích để sàng lọc các biến không được khai báo

Khi từ khóa typeof trả về "object" thì chúng ta biết biến đã được khai báo và được gán một đối tượng hoặc một giá trị Object.prototype.toString.call([])0

Trong khi đó, typeof sẽ trả về Object.prototype.toString.call([])80 cho các biến không được khai báo thay vì trả về Object.prototype.toString.call([])29, điều này sẽ hữu ích nếu bạn kiểm tra typeof trước nếu bạn cho rằng mình có thể đang làm việc với một biến chưa được khai báo

Khi chúng ta biết biến được khai báo bằng cách sử dụng typeof (dù là Object.prototype.toString.call([])84 hay Object.prototype.toString.call([])85), chúng ta có thể sử dụng chắc chắn typeof []2

Kiểm tra các mảng trống

Cuối cùng, khi chắc chắn chúng ta có một mảng (i. e. khi typeof []2 trả về Object.prototype.toString.call([])38), chúng ta có thể kiểm tra xem mảng có trống hay không bằng cách sử dụng Object.prototype.toString.call([])36

Một Object.prototype.toString.call([])36 của Object.prototype.toString.call([])37 biểu thị một mảng JavaScript trống typeof1 , trong khi một mảng có Object.prototype.toString.call([])93 biểu thị một mảng không trống

Lưu ý rằng mảng trống typeof1 là true, nghĩa là nó trả về true khi được đánh giá là Boolean. (typeof1 là trung thực vì tất cả các đối tượng đều trung thực. )

Phương pháp tốt nhất để kiểm tra một mảng

Tôi đã đề cập đến 5 phương pháp kiểm tra mảng JavaScript khác nhau. Tôi thường sử dụng typeof []2 khi viết mã vì nhiều lý do

  • typeof []2 nhanh chóng và được hỗ trợ rộng rãi
  • typeof []2 rõ ràng, làm cho mã của bạn dễ đọc hơn
  • typeof []2 trả lại "object"5 cho typeof []3 và "object"3

Đôi khi, tôi sẽ gói kiểm tra mảng của mình bên trong câu lệnh typeof []03 trong trường hợp hiếm hoi mà tôi lo lắng về các biến không được khai báo

Nhưng nếu không, tôi sẽ chỉ sử dụng typeof []2 — nó chỉ hoạt động

Bây giờ hãy ra khỏi đó và tự tin kiểm tra các mảng

Mã hóa vui vẻ. 💻🎶👓💯🤩

đọc thêm

  • Mã Với Hugo bao gồm typeof []2 với tất cả các loại dữ liệu có thể

Kiểm tra kiểu mảng JavaScript - "là mảng" so với đối tượng chuyên sâu · Viết mã với Hugo

Ví dụ cho phần này tại observablehq. com/@hugodf/javascript-array-detection-using-array-isarray, bạn có thể chơi…

codewithhugo. com

  • Tác giả xuất sắc Samantha Ming thảo luận về lý do tại sao không sử dụng "object"1

Kiểm tra Array tốt hơn với Array. làArray

Vì mảng không phải là mảng thực trong JavaScript nên không có kiểu kiểm tra đơn giản nào. Không vấn đề gì. Sử dụng phương pháp…

trung bình. com

  • Tác giả Moon mô tả phương pháp Object.prototype.toString.call([]) chi tiết hơn trong Lập trình tốt hơn

[Đối tượng đối tượng] trong JavaScript là gì. Mục tiêu. nguyên mẫu. toString

Giải thích sâu hơn về [đối tượng Đối tượng]

trung bình. com

  • Trước đây tôi đã viết về những cạm bẫy của typeof trong Lập trình tốt hơn

Cách kiểm tra các loại dữ liệu trong JavaScript bằng typeof

Kiểm tra một trong chín chuỗi. không xác định, đối tượng (null), boolean, số, bigint, chuỗi, ký hiệu, hàm hoặc đối tượng…

trung bình. com

  • Tôi cũng đã viết về phương pháp Object.prototype.toString.call([]) để kiểm tra loại trong một bài viết bằng JavaScript bằng tiếng Anh thuần túy

Cách tốt nhất để nhập kiểm tra trong Vanilla JS

Cách tốt nhất để kiểm tra loại biến trong JavaScript không phải là typeof. Đây là lý do tại sao nên sử dụng…

trung bình. com

  • Brandon Morelli giải thích rõ về toán tử đoản mạch trong CodeBurst

JavaScript. Đánh giá ngắn mạch là gì?

Tìm hiểu cách sử dụng logic OR (. ) có lợi cho bạn khi gán biến

mật mã. io

Tiến sĩ. Derek Austin là tác giả của Lập trình nghề nghiệp. Làm thế nào bạn có thể trở thành một lập trình viên có thân hình 6 con số thành công trong 6 tháng, hiện đã có trên Amazon

Có loại mảng trong JavaScript không?

Mảng đã nhập JavaScript là các đối tượng giống như mảng cung cấp cơ chế đọc và ghi dữ liệu nhị phân thô trong bộ nhớ đệm . Các đối tượng mảng phát triển và thu nhỏ linh hoạt và có thể có bất kỳ giá trị JavaScript nào. Các công cụ JavaScript thực hiện tối ưu hóa để các mảng này hoạt động nhanh.

Làm cách nào để kiểm tra loại trong JavaScript?

Việc kiểm tra kiểu JavaScript không nghiêm ngặt như các ngôn ngữ lập trình khác. Sử dụng toán tử typeof để phát hiện các loại . Có hai biến thể của cú pháp toán tử typeof. typeof và typeof(biểu thức).