JavaScript Có thể Lặp lại Không mong đợi


83

Tôi có mã sau:

  for (i in awards) {
         if (awards[i] instanceof Array === false) {
               console.log(awards[i]);
                httpFactory.patch(awards[i], {"read": true}, false);
             }
       }

IDE của tôi hiển thị lỗi này liên quan đến mã ở trên:

Có thể lặp lại các thành viên không mong muốn (tùy chỉnh / kế thừa), có thể thiếu kiểm tra hasOwnProperty

Kiểm tra bất kỳ trường hợp nào của vòng lặp bổ sung chưa được lọc trong JavaScript. Việc sử dụng cấu trúc này dẫn đến việc xử lý các thuộc tính kế thừa hoặc không mong đợi. Bạn cần lọc các thuộc tính riêng bằng phương thức hasOwnProperty (). Xác thực hoạt động trong các tệp JavaScript, html hoặc jsp.

Bạn có thể giải thích chi tiết hơn ý nghĩa của câu nói này không?


2
jQuery không thực hiện hasOwnPropertykiểm tra - Tôi tự hỏi có bao nhiêu cảnh báo sẽ tạo ra ....
Alnitak

Câu trả lời:


145

IDE khuyên bạn nên thêm một bài kiểm tra:

if (awards.hasOwnProperty(i)) {
    ...
}

bên trong forvòng lặp.

Cá nhân tôi khuyên bạn không nên làm điều này và tắt cảnh báo nếu có thể. Đơn giản là không cần hầu hết các mã và thậm chí ít cần hơn trong mã ES5, nơi bạn có thể thêm các thuộc tính không liệt kê một cách an toàn vào một đối tượng bằng cách sử dụngObject.defineProperty

Việc hasOwnPropertykiểm tra chỉ cần thiết nếu bạn đã thêm các thuộc tính mới (có thể liệt kê) vào một cách không an toàn Object.prototype, vì vậy cách khắc phục đơn giản nhất là không làm điều đó .

jQuery không thực hiện kiểm tra này - họ ghi rõ ràng rằng jQuery sẽ bị Object.prototypehỏng nếu được sửa đổi không an toàn.


40
Trong IntelliJ 15, để tắt cảnh báo, hãy thực hiện như sau: Mở Tùy chọn -> Trình chỉnh sửa -> Kiểu mã -> Kiểm tra. Trong hộp tìm kiếm, nhập "hasOwnProperty". Nó sẽ hiển thị "Unfiltered for..in loop". Bỏ chọn hộp đó. Nhấp vào nút OK để chấp nhận thay đổi và đóng cửa sổ.
Machtyn

2
Trong IntelliJ: CTRL ALT S (trừ khi bạn đang sử dụng Ubuntu có phím tắt CTRL ALT S của riêng nó) chỉ cần tìm kiếm "hasOwnProperty" và bạn sẽ đi thẳng vào vấn đề, bỏ chọn và hoàn tất!
Olivier Pons

1
Trong WebStorm, đi tới Cài đặt Tệp ..., rồi đến Trình chỉnh sửa -> Kiểm tra -> "JavaScript và TypeScript" -> Chung, và bỏ chọn "Vòng lặp for..in không được lọc".
Strongpile

21

Mọi đối tượng trong javascript đều có nguyên mẫu có các thuộc tính riêng (phương thức / thuộc tính gốc / kế thừa) và các thuộc tính được gắn trực tiếp vào chính đối tượng.

Khi bạn lặp qua một đối tượng, nó sẽ lặp lại các thuộc tính của chính đối tượng đó và các thuộc tính của nguyên mẫu của đối tượng.

Vì vậy, để tránh lặp lại nguyên mẫu, bạn nên sử dụng phương thức hasOwnProperty chỉ trả về true khi đối tượng có thuộc tính được đề cập trực tiếp. tức là, Không phải bên trong nguyên mẫu

Thí dụ

for (var k in object) {
  if (object.hasOwnProperty(k)) {
     // do your computation here.
  }
}

Thông tin chi tiết có thể được tìm thấy tại đây


13

Bạn cũng có thể cấu trúc lại vòng lặp của mình thành:

const keys = Object.keys(object);
for (const key of keys){
   // do something with object[key];
}

3

Ngoài ra, bạn có thể loại bỏ cảnh báo viết vòng lặp forEach để có cách tiếp cận chức năng và dễ đọc hơn:

Object.keys(object).forEach(key => {
    // Do something with object[key]
});

-2

bạn nên thêm một điều kiện nữa vào đầu vòng lặp này

if (awards.hasOwnProperty(i)) 

13
Tôi đã bỏ phiếu cho câu trả lời này, vì vậy tôi nghĩ rằng thật lịch sự nếu tôi nói tại sao. Câu trả lời này cho biết cách tránh cảnh báo nhưng nó không giải thích ý nghĩa của cảnh báo, cách tránh nó hoặc mã này làm gì.
WoodenKitty
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.