EcmaScript 6
Nếu bạn đang sử dụng ES6, bạn có thể tạo một mảng các mục và sử dụng includes
:
['a', 'b', 'c'].includes('b')
Điều này có một số lợi ích vốn có indexOf
vì nó có thể kiểm tra chính xác sự hiện diện củaNaN
trong danh sách, và có thể phù hợp với thiếu phần tử mảng như một trong những trung ở [1, , 2]
đến undefined
. includes
cũng hoạt động trên các mảng gõ JavaScript như Uint8Array
.
Nếu bạn lo lắng về hỗ trợ trình duyệt (chẳng hạn như IE hoặc Edge), bạn có thể kiểm tra Array.includes
tại CanIUse.Com và nếu bạn muốn nhắm mục tiêu một trình duyệt hoặc phiên bản trình duyệt bị thiếu includes
, tôi khuyên bạn nên sử dụng polyfill.io cho polyfill.
Không có một mảng
Bạn có thể thêm một thuộc tính mới isInList
vào chuỗi như sau:
if (!String.prototype.isInList) {
String.prototype.isInList = function() {
let value = this.valueOf();
for (let i = 0, l = arguments.length; i < l; i += 1) {
if (arguments[i] === value) return true;
}
return false;
}
}
Sau đó sử dụng nó như vậy:
'fox'.isInList('weasel', 'fox', 'stoat') // true
'fox'.isInList('weasel', 'stoat') // false
Bạn có thể làm điều tương tự cho Number.prototype
.
Mảng.indexOf
Nếu bạn đang sử dụng một trình duyệt hiện đại, indexOf
luôn hoạt động. Tuy nhiên, đối với IE8 trở về trước, bạn sẽ cần một polyfill.
Nếu indexOf
trả về -1, mục này không có trong danh sách. Mặc dù vậy, hãy chú ý rằng phương pháp này sẽ không kiểm tra chính xác NaN
và trong khi nó có thể khớp với một phần tử rõ ràng undefined
, thì nó không thể khớp với một phần tử bị thiếu undefined
như trong mảng[1, , 2]
.
Polyfill cho indexOf
hoặcincludes
trong IE hoặc bất kỳ trình duyệt / phiên bản nào khác thiếu hỗ trợ
Nếu bạn không muốn sử dụng một dịch vụ như polyfill.io như đã đề cập ở trên, bạn luôn có thể đưa vào các polyfill tùy chỉnh tuân thủ tiêu chuẩn mã nguồn của riêng bạn. Ví dụ: Mozilla Developer Network có một choindexOf
.
Trong tình huống này khi tôi phải thực hiện một giải pháp cho Internet Explorer 7, tôi đã "tự lăn" phiên bản đơn giản hơn của indexOf()
chức năng không tuân thủ tiêu chuẩn:
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(item) {
var i = this.length;
while (i--) {
if (this[i] === item) return i;
}
return -1;
}
}
Tuy nhiên, tôi không nghĩ sửa đổi Array.prototype
là câu trả lời tốt nhất trong dài hạn. Sửa đổi Object
và Array
nguyên mẫu trong JavaScript có thể dẫn đến các lỗi nghiêm trọng. Bạn cần phải quyết định xem làm như vậy có an toàn trong môi trường của chính bạn hay không. Lưu ý chính là việc lặp lại một mảng (khi Array.prototype có thêm thuộc tính) vớifor ... in
sẽ trả về tên hàm mới là một trong các khóa:
Array.prototype.blah = function() { console.log('blah'); };
let arr = [1, 2, 3];
for (let x in arr) { console.log(x); }
// Result:
0
1
2
blah // Extra member iterated over!
Mã của bạn có thể hoạt động ngay bây giờ, nhưng thời điểm ai đó trong tương lai thêm thư viện hoặc plugin JavaScript của bên thứ ba không thực sự bảo vệ chống lại các khóa được kế thừa, mọi thứ đều có thể bị phá vỡ.
Cách cũ để tránh sự phá vỡ đó là, trong quá trình liệt kê, kiểm tra từng giá trị để xem liệu đối tượng có thực sự là tài sản không được thừa kế với if (arr.hasOwnProperty(x))
và chỉ sau đó làm việc với nó khôngx
.
Cách ES6 mới để tránh vấn đề phụ này là sử dụng of
thay vì in
, for (let x of arr)
. Tuy nhiên, trừ khi bạn có thể đảm bảo rằng tất cả các thư viện mã và bên thứ ba của bạn tuân thủ nghiêm ngặt phương pháp này, thì với mục đích của câu hỏi này, có lẽ bạn sẽ chỉ muốn sử dụng includes
như đã nêu ở trên.