2015-08-12 17 views
6

Bạn nên luôn sử dụng hasOwnProperty, nhưng trong nhiều trường hợp, điều này là không cần thiết. Ví dụ xem xét đoạn mã sau:hasOwnProperty khi nào cần sử dụng và khi nào không cần thiết?

var object = JSON.parse(somejsontext); 
for(var prop in object) { 
    console.log(object[prop]); 
} 

Tôi biết trong trường hợp này mà prop là một phần của đối tượng, nó được xác định bởi các explict for..in.

Nhưng theo MOZ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty chúng ta nên sử dụng nó để tránh iterating qua đạo cụ phi enumarable, với ví dụ này:

var buz = { 
    fog: 'stack' 
}; 

for (var name in buz) { 
    if (buz.hasOwnProperty(name)) { 
    console.log('this is fog (' + name + ') for sure. Value: ' + buz[name]); 
    } 
    else { 
    console.log(name); // toString or something else 
    } 
} 

Nhưng kiểm tra mã này trên thực tế, không bao giờ đi vào khác.

Vì vậy, khi nào có ý nghĩa khi sử dụng hasOwnProperty?

UPDATE: Xem xét câu trả lời choosen, chúng tôi safetly có thể tránh được việc sử dụng các hasOwnProperty trong trường hợp này: - Object js chưa được mở rộng bởi bất kỳ thư viện javascript hoặc bởi mã của chúng tôi - Object là một mã đơn giản mà chúng ta có thể kiểm soát trên

+0

http://stackoverflow.com/questions/13632999/if-key-in-object-or-ifobject-hasownpropertykey – Andreas

Trả lời

7

Sự cố xảy ra khi một nguyên mẫu bao gồm các thuộc tính có thể đếm được mà mã của bạn không lường trước được. Ví dụ, giả sử này chạy ngay trước ví dụ của bạn:

Object.prototype.foobar = "hello"; 

Trong trường hợp này, iterating trên buz sẽ bao gồm các tài sản đếm được foobar nguyên mẫu. Mẫu hasOwnProperty này cho phép mã của bạn phân biệt giữa các thuộc tính là trực tiếp trên đối tượng, so với các thuộc tính được kế thừa từ tổ tiên nguyên mẫu.

Vấn đề không phải là "liệt kê các thuộc tính không thể đếm được" (nghĩa là không thể xác định được, trừ khi bạn nhận được chúng một cách rõ ràng qua getOwnPropertyNames cho mỗi cấp của phân cấp nguyên mẫu), chứ không liệt kê các thuộc tính kế thừa. Đây là một mối quan ngại khi sử dụng các thư viện có thể thêm các thuộc tính liệt kê vào các nguyên mẫu cấp cao, chính xác như tôi đã minh họa ở trên.

Nếu bạn muốn thêm một tài sản để một nguyên mẫu mà không gây ra rằng tài sản được liệt kê, bạn có thể làm cho một tài sản phi đếm được với Object.defineProperty:

Object.defineProperty(Object.prototype, "foobar", { 
    value: "hello", 
    enumerable: false, 
    writeable: true, 
    configurable: true 
}); 

một tài sản như vậy sẽ không xuất hiện trong một for..in vòng lặp trên buz (hoặc trong vòng for..in trực tiếp trên Object.prototype, một trong hai).

+0

có nhưng nó sẽ không có ý nghĩa khi có sự kiểm soát của bạn mã, (hy vọng rằng một thư viện nào không mở rộng nguyên mẫu của đối tượng cơ bản) – albanx

+0

@albanx Nhiều thư viện mở rộng nhiều đối tượng gốc, ngay cả 'Object.prototype' có thể được mở rộng. – Teemu

+0

Nhưng trong ví dụ mozilla tại sao nó không itarete thông qua phương pháp toString. . – albanx

Các vấn đề liên quan