ถ้าฉันเข้าใจถูกต้องแต่ละออบเจ็กต์ใน JavaScript จะสืบทอดมาจาก Object ต้นแบบ
อาจดูเหมือนการแบ่งเส้นขน แต่มีความแตกต่างระหว่างJavaScript (คำทั่วไปสำหรับการใช้งาน ECMAScript) และECMAScript (ภาษาที่ใช้สำหรับการใช้งาน JavaScript) เป็น ECMAScript ที่กำหนดโครงร่างการสืบทอดไม่ใช่ JavaScript ดังนั้นเฉพาะอ็อบเจ็กต์ ECMAScript ดั้งเดิมเท่านั้นที่ต้องใช้โครงร่างการสืบทอดนั้น
โปรแกรม JavaScript ที่รันอยู่ประกอบด้วยอ็อบเจ็กต์ ECMAScript ในตัว (Object, Function, Number เป็นต้น) เป็นอย่างน้อยและอาจเป็นอ็อบเจ็กต์ดั้งเดิม (เช่นฟังก์ชัน) นอกจากนี้ยังอาจมีวัตถุโฮสต์บางอย่าง (เช่นวัตถุ DOM ในเบราว์เซอร์หรือวัตถุอื่น ๆ ในสภาพแวดล้อมโฮสต์อื่น ๆ )
แม้ว่าออบเจ็กต์ในตัวและเนทีฟต้องใช้โครงร่างการสืบทอดที่กำหนดไว้ใน ECMA-262 แต่ออบเจ็กต์โฮสต์ไม่ ดังนั้นไม่ทั้งหมดวัตถุในสภาพแวดล้อม JavaScript ต้องรับมรดกจากObject.prototype ตัวอย่างเช่นโฮสต์อ็อบเจ็กต์ใน Internet Explorer ที่นำไปใช้เป็นอ็อบเจ็กต์ActiveXจะทำให้เกิดข้อผิดพลาดหากถือว่าเป็นเนทีฟอ็อบเจ็กต์ (ด้วยเหตุนี้จึงใช้try..catchเพื่อเริ่มต้นอ็อบเจ็กต์Microsoft XMLHttpRequest ) อ็อบเจ็กต์ DOM บางตัว (เช่น NodeLists ใน Internet Explorer ในโหมด quirks) หากส่งผ่านไปยังเมธอด Array จะทำให้เกิดข้อผิดพลาดอ็อบเจ็กต์ DOM ใน Internet Explorer 8 และต่ำกว่าไม่มีโครงร่างการสืบทอดเช่น ECMAScript เป็นต้น
ดังนั้นจึงไม่ควรสันนิษฐานว่าอ็อบเจ็กต์ทั้งหมดในสภาพแวดล้อม JavaScript สืบทอดมาจาก Object.prototype
ซึ่งหมายความว่าแต่ละอ็อบเจ็กต์ใน JavaScript สามารถเข้าถึงฟังก์ชัน hasOwnProperty ผ่านห่วงโซ่ต้นแบบ
ซึ่งไม่เป็นความจริงสำหรับวัตถุโฮสต์บางอย่างใน Internet Explorer ในโหมด quirks (และ Internet Explorer 8 และต่ำกว่าเสมอ) เป็นอย่างน้อย
จากที่กล่าวมาคุณควรพิจารณาว่าเหตุใดวัตถุจึงอาจมีเมธอดhasOwnPropertyของตัวเองและความเหมาะสมในการเรียกใช้เมธอดhasOwnPropertyอื่น ๆแทนโดยไม่ต้องทดสอบก่อนว่าเป็นความคิดที่ดีหรือไม่
ฉันสงสัยว่าสาเหตุของการใช้Object.prototype.hasOwnProperty.call
คือในบางเบราว์เซอร์วัตถุโฮสต์ไม่มีเมธอดhasOwnPropertyการใช้การโทรและวิธีการในตัวเป็นอีกทางเลือกหนึ่ง อย่างไรก็ตามการทำเช่นนั้นโดยทั่วไปดูเหมือนจะไม่ใช่ความคิดที่ดีสำหรับเหตุผลที่ระบุไว้ข้างต้น
ในกรณีที่เกี่ยวข้องกับวัตถุโฮสต์สามารถใช้ตัวดำเนินการinเพื่อทดสอบคุณสมบัติโดยทั่วไปเช่น
var o = document.getElementsByTagName('foo');
o.hasOwnProperty('bar');
('bar' in o);
Object.prototype.hasOwnProperty.call(o, 'bar');
ทางเลือกอื่น (ทดสอบในInternet Explorer 6และอื่น ๆ ):
function ownProp(o, prop) {
if ('hasOwnProperty' in o) {
return o.hasOwnProperty(prop);
} else {
return Object.prototype.hasOwnProperty.call(o, prop);
}
}
ด้วยวิธีนี้คุณจะเรียกใช้hasOwnPropertyในตัวโดยเฉพาะซึ่งอ็อบเจ็กต์ไม่มี (สืบทอดหรืออย่างอื่น)
อย่างไรก็ตามหากออบเจ็กต์ไม่มีhasOwnProperty
เมธอดก็น่าจะเหมาะสมที่จะใช้อินโอเปอเรเตอร์เนื่องจากอ็อบเจกต์น่าจะไม่มีโครงร่างการสืบทอดและคุณสมบัติทั้งหมดอยู่บนอ็อบเจกต์ (นั่นเป็นเพียงข้อสันนิษฐานเท่านั้น) เช่นในตัวดำเนินการเป็นวิธีทดสอบทั่วไป (และดูเหมือนจะประสบความสำเร็จ) สำหรับการสนับสนุนวัตถุ DOM สำหรับคุณสมบัติ