Do hai câu lệnh sau tạo ra cùng một đầu ra? Có bất kỳ lý do để thích cách này hơn cách khác?
if (key in object)
if (object.hasOwnProperty(key))
Do hai câu lệnh sau tạo ra cùng một đầu ra? Có bất kỳ lý do để thích cách này hơn cách khác?
if (key in object)
if (object.hasOwnProperty(key))
Câu trả lời:
Hãy cẩn thận - họ sẽ không tạo ra kết quả tương tự.
incũng sẽ trả về truenếu keyđược tìm thấy ở đâu đó trong chuỗi nguyên mẫu , trong khi Object.hasOwnProperty(như tên đã nói với chúng tôi), sẽ chỉ trả về truenếu keycó sẵn trên đối tượng đó ("sở hữu" tài sản của nó).
({foo:"bar"}).hasOwnProperty("toString")vs"toString" in ({foo:"bar"})
Tôi sẽ cố gắng giải thích với một ví dụ khác. Giả sử chúng ta có đối tượng sau với hai thuộc tính:
function TestObj(){
this.name = 'Dragon';
}
TestObj.prototype.gender = 'male';
Hãy tạo phiên bản TestObj:
var o = new TestObj();
Hãy xem xét ví dụ đối tượng:
console.log(o.hasOwnProperty('name')); // true
console.log('name' in o); // true
console.log(o.hasOwnProperty('gender')); // false
console.log('gender' in o); // true
Phần kết luận:
trong toán tử trả về true luôn, nếu đối tượng có thể truy cập thuộc tính, trực tiếp hoặc từ nguyên mẫu
hasOwnProperty () chỉ trả về true nếu thuộc tính tồn tại trên cá thể, nhưng không phải trên nguyên mẫu của nó
Nếu chúng ta muốn kiểm tra xem một số thuộc tính có tồn tại trên nguyên mẫu hay không, chúng ta sẽ nói:
console.log(('name' in o) && !o.hasOwnProperty('name')); //false
console.log(('gender' in o) && !o.hasOwnProperty('gender')); //true - it's in prototype
Cuối cùng:
Vì vậy, liên quan đến tuyên bố rằng hai điều kiện này ...
if (key in object)
if (object.hasOwnProperty(key))
... tạo ra kết quả tương tự, câu trả lời là rõ ràng, nó phụ thuộc.
incũng sẽ kiểm tra các thuộc tính được kế thừa, đây không phải là trường hợp hasOwnProperty.
Tóm lại, hasOwnProperty()không nhìn vào nguyên mẫu trong khi inkhông nhìn vào nguyên mẫu.
Lấy từ Javascript hiệu suất cao của O'Reilly :
Bạn có thể xác định liệu một đối tượng có một thành viên thể hiện với một tên cụ thể hay không bằng cách sử dụng phương thức hasOwnProperty () và chuyển vào tên của thành viên đó. Để xác định xem một đối tượng có quyền truy cập vào một thuộc tính có tên đã cho hay không, bạn có thể sử dụng toán tử in. Ví dụ:
var book = {
title: "High Performance JavaScript",
publisher: "Yahoo! Press"
};
alert(book.hasOwnProperty("title")); //true
alert(book.hasOwnProperty("toString")); //false
alert("title" in book); //true
alert("toString" in book); //true
Trong mã này, hasOwnProperty () trả về true khi tiêu đề của Wikipedia được truyền vào vì tiêu đề là một thể hiện đối tượng; phương thức trả về false khi được chuyển vào. Khi mỗi tên thuộc tính được sử dụng với toán tử in, kết quả là đúng cả hai lần vì nó tìm kiếm thể hiện và nguyên mẫu.
Bạn có một số câu trả lời thực sự tuyệt vời. Tôi chỉ muốn cung cấp một cái gì đó sẽ giúp bạn tiết kiệm nhu cầu kiểm tra "hasOwnProperty" trong khi lặp lại một đối tượng.
Khi tạo một đối tượng thường mọi người sẽ tạo nó theo cách này:
const someMap = {}
// equivalent to: Object.create(Object.prototype)
// someMap.constructor will yield -> function Object() { [native code] }
Bây giờ, nếu bạn muốn lặp qua "someMap", bạn sẽ phải làm theo cách này:
const key
for(key in someMap ){
if (someMap.hasOwnProperty(key)) {
// Do something
}
}
Chúng tôi đang làm như vậy để tránh lặp lại các thuộc tính được thừa kế.
Nếu bạn định tạo một đối tượng đơn giản sẽ chỉ được sử dụng làm "bản đồ" (tức là cặp khóa - giá trị), bạn có thể làm như vậy:
const newMap = Object.create(null);
// Now, newMap won't have prototype at all.
// newMap.constructor will yield -> undefined
Vì vậy, bây giờ sẽ an toàn để lặp lại như thế này:
for(key in cleanMap){
console.log(key + " -> " + newMap [key]);
// No need to add extra checks, as the object will always be clean
}
Tôi đã học được mẹo tuyệt vời này ở đây
Dạng khác (được gọi là in) liệt kê tên thuộc tính (hoặc khóa) của một đối tượng. Trên mỗi lần lặp, một chuỗi tên thuộc tính khác từ đối tượng được gán cho biến. Thông thường cần phải kiểm tra object.hasOwnProperty (biến) để xác định xem tên thuộc tính có thực sự là thành viên của đối tượng hay được tìm thấy thay thế trên chuỗi nguyên mẫu.
for (myvar in obj) {
if (obj.hasOwnProperty(myvar)) { ... } }
(từ Javascript của Crockford : Bộ phận tốt )
innhà khai thác khác với for-intuyên bố.
inlà một từ khóa. Nhưng OP đang hỏi về cách sử dụng cụ thể như innhà điều hành. Câu trả lời của bạn liên quan đến việc sử dụng khác như một phần của for-intuyên bố.
Phiên bản đầu tiên ngắn hơn (đặc biệt là mã được rút gọn trong đó các biến được đổi tên)
a in b
đấu với
b.hasOwnProperty(a)
Dù sao, như @AndreMeinhold đã nói, không phải lúc nào họ cũng tạo ra kết quả tương tự.
in will also return true if key gets found somewhere in the prototype chain. bạn có thể viết một ví dụ không? cảm ơn.