สองข้อความต่อไปนี้สร้างเอาต์พุตเดียวกันหรือไม่? มีเหตุผลใดที่จะชอบอีกทางหนึ่ง?
if (key in object)
if (object.hasOwnProperty(key))
สองข้อความต่อไปนี้สร้างเอาต์พุตเดียวกันหรือไม่? มีเหตุผลใดที่จะชอบอีกทางหนึ่ง?
if (key in object)
if (object.hasOwnProperty(key))
คำตอบ:
ระวัง - พวกเขาจะไม่ให้ผลลัพธ์เดียวกัน
inนอกจากนี้ยังจะกลับมาtrueถ้าkeyได้รับที่ไหนสักแห่งที่พบในห่วงโซ่ต้นแบบในขณะที่Object.hasOwnProperty(เช่นชื่อที่มีอยู่แล้วบอกเรา) เพียงจะกลับมาtrueถ้าkeyมีอยู่ในวัตถุที่โดยตรง (ของ "เจ้าของ" ทรัพย์สิน)
({foo:"bar"}).hasOwnProperty("toString")vs"toString" in ({foo:"bar"})
ฉันพยายามอธิบายด้วยตัวอย่างอื่น สมมติว่าเรามีวัตถุต่อไปนี้พร้อมด้วยคุณสมบัติสองประการ:
function TestObj(){
this.name = 'Dragon';
}
TestObj.prototype.gender = 'male';
มาสร้างตัวอย่างของ TestObj:
var o = new TestObj();
ตรวจสอบตัวอย่างวัตถุ:
console.log(o.hasOwnProperty('name')); // true
console.log('name' in o); // true
console.log(o.hasOwnProperty('gender')); // false
console.log('gender' in o); // true
สรุป:
ในตัวดำเนินการส่งคืนจริงเสมอถ้าคุณสมบัติสามารถเข้าถึงได้โดยวัตถุโดยตรงหรือจากต้นแบบ
hasOwnProperty () จะส่งคืนค่า true หากมีคุณสมบัติอยู่ในอินสแตนซ์ แต่จะไม่แสดงผลบนต้นแบบ
ถ้าเราต้องการตรวจสอบว่ามีคุณสมบัติบางอย่างอยู่บนต้นแบบเราจะพูดว่า:
console.log(('name' in o) && !o.hasOwnProperty('name')); //false
console.log(('gender' in o) && !o.hasOwnProperty('gender')); //true - it's in prototype
สุดท้าย:
ดังนั้นเกี่ยวกับคำแถลงว่าเงื่อนไขสองข้อนี้ ...
if (key in object)
if (object.hasOwnProperty(key))
... สร้างผลลัพธ์เดียวกันคำตอบนั้นชัดเจนขึ้นอยู่กับ
inhasOwnPropertyนอกจากนี้ยังจะตรวจสอบคุณสมบัติได้รับมรดกซึ่งไม่ได้เป็นกรณีที่
โดยสรุปhasOwnProperty()ไม่ดูในต้นแบบขณะที่inดูในต้นแบบ
นำมาจากJavascript ประสิทธิภาพสูงของ O'Reilly :
คุณสามารถตรวจสอบว่าวัตถุมีสมาชิกอินสแตนซ์ที่มีชื่อที่กำหนดโดยใช้วิธีการ hasOwnProperty () และส่งผ่านในชื่อของสมาชิก ในการตรวจสอบว่าวัตถุมีการเข้าถึงคุณสมบัติที่มีชื่อที่กำหนดหรือไม่คุณสามารถใช้ตัวดำเนินการ in ตัวอย่างเช่น:
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
ในรหัสนี้ hasOwnProperty () จะคืนค่าจริงเมื่อมีการส่ง“ ชื่อเรื่อง” เนื่องจากชื่อเรื่องเป็นอินสแตนซ์ของวัตถุ เมธอดจะส่งคืนค่าเท็จเมื่อส่งผ่าน“ toString” เนื่องจากไม่มีอยู่ในอินสแตนซ์ เมื่อแต่ละชื่อคุณสมบัติถูกใช้กับตัวดำเนินการ in ผลลัพธ์จะเป็นจริงทั้งสองครั้งเนื่องจากค้นหาอินสแตนซ์และแบบตัวอย่าง
คุณได้คำตอบที่ยอดเยี่ยมจริงๆ ฉันแค่ต้องการเสนอสิ่งที่จะช่วยให้คุณไม่ต้องตรวจสอบ "hasOwnProperty" ในขณะที่วนวัตถุ
เมื่อสร้างวัตถุคนมักจะสร้างวัตถุด้วยวิธีนี้:
const someMap = {}
// equivalent to: Object.create(Object.prototype)
// someMap.constructor will yield -> function Object() { [native code] }
ตอนนี้ถ้าคุณต้องการทำซ้ำผ่าน "someMap" คุณจะต้องทำเช่นนี้:
const key
for(key in someMap ){
if (someMap.hasOwnProperty(key)) {
// Do something
}
}
เรากำลังทำเช่นนั้นเพื่อหลีกเลี่ยงการวนซ้ำคุณสมบัติที่สืบทอดมา
หากคุณต้องการสร้างวัตถุอย่างง่ายที่จะใช้เป็น "แผนที่" เท่านั้น (เช่นคู่ของคีย์ - ค่า) คุณสามารถทำได้เช่นนั้น:
const newMap = Object.create(null);
// Now, newMap won't have prototype at all.
// newMap.constructor will yield -> undefined
ดังนั้นตอนนี้จะปลอดภัยที่จะวนซ้ำเช่นนี้:
for(key in cleanMap){
console.log(key + " -> " + newMap [key]);
// No need to add extra checks, as the object will always be clean
}
รูปแบบอื่น ๆ (เรียกว่าสำหรับ) ระบุชื่อคุณสมบัติ (หรือคีย์) ของวัตถุ ในแต่ละการวนซ้ำสตริงชื่อคุณสมบัติอื่นจากวัตถุถูกกำหนดให้กับตัวแปร โดยปกติแล้วมันเป็นสิ่งจำเป็นในการทดสอบ object.hasOwnProperty (ตัวแปร) เพื่อตรวจสอบว่าชื่อคุณสมบัติเป็นสมาชิกของวัตถุอย่างแท้จริงหรือถูกค้นพบแทนบนสายโซ่ต้นแบบ
for (myvar in obj) {
if (obj.hasOwnProperty(myvar)) { ... } }
(จากJavascriptของ Crockford : ส่วนที่ดี )
inผู้ประกอบการมีความแตกต่างกว่าfor-inคำสั่ง
inเป็นคำหลัก แต่ OP กำลังถามเกี่ยวกับการใช้งานเฉพาะในฐานะinผู้ให้บริการ คำตอบของคุณเกี่ยวข้องกับการใช้งานอื่น ๆ ซึ่งเป็นส่วนหนึ่งของfor-inคำชี้แจง
รุ่นแรกสั้นกว่า (โดยเฉพาะในรหัสย่อที่ตัวแปรจะถูกเปลี่ยนชื่อ)
a in b
VS
b.hasOwnProperty(a)
อย่างไรก็ตามตามที่ @AndreMeinhold กล่าวว่าพวกเขาไม่ได้ให้ผลลัพธ์ที่เหมือนกันเสมอไป
in will also return true if key gets found somewhere in the prototype chainทำในสิ่งที่คุณหมายถึงว่าสำหรับ คุณสามารถเขียนตัวอย่างได้หรือไม่ ขอบคุณ