המתודה hasOwnProperty() ב-JavaScript היא חיונית להבחנה בין מאפיינים שנמצאים בבעלות האובייקט לבין מאפיינים (properties) שירש משרשרת ה-Prototype שלו. מתודה זו בודקת אם מאפיין מסוים הוא מאפיין ישיר של האובייקט ולא מאפיין שעבר בירושה, ומחזירה ערך בוליאני בהתאם.
אם ברצונכם להבין את הבסיס, עיינו בפוסט שלנו על אובייקטים ב-JavaScript למתחילים.
כיצד עובדת המתודה hasOwnProperty()
את המתודה hasOwnProperty() מפעילים על אובייקט, תוך העברת שם המאפיין שברצונכם לבדוק כמחרוזת. המתודה מחזירה true אם המאפיין הוא מאפיין ישיר של האובייקט ו-false בכל מקרה אחר. מתודה זו אינה בודקת את שרשרת הפרוטוטייפ.
דוגמה פשוטה 1: בדיקת מאפיינים של אובייקט
const car = {
make: 'Toyota',
model: 'Corolla'
};
console.log(car.hasOwnProperty('make')); // Output: true
console.log(car.hasOwnProperty('year')); // Output: false
דוגמה זו מראה כיצד להשתמש במתודה hasOwnProperty() כדי לבדוק אם מאפיינים מסוימים מוגדרים ישירות באובייקט, ובכך להבחין בין מאפיינים קיימים לבין כאלה שאינם קיימים.
דוגמה פשוטה 2: שימוש ב-hasOwnProperty בתוך פונקציה
function hasProperty(obj, prop) {
return obj.hasOwnProperty(prop);
}
const bike = {
brand: 'Trek',
type: 'mountain'
};
console.log(hasProperty(bike, 'brand')); // Output: true
console.log(hasProperty(bike, 'price')); // Output: false
דוגמה זו מדגימה כיצד לעטוף את המתודה hasOwnProperty() בתוך פונקציה כדי ליצור כלי שימושי לבדיקת מאפיינים באובייקטים.
דוגמה מורכבת: סינון מאפיינים בירושה
בדוגמה זו נלמד כיצד לסנן מאפיינים ישירים של אובייקט ממאפיינים שירש מהפרוטוטייפ שלו.
function Vehicle(type) {
this.type = type;
}
Vehicle.prototype.start = function() {
return 'Starting...';
};
const car = new Vehicle('Car');
car.make = 'Toyota';
car.model = 'Corolla';
for (let prop in car) {
if (car.hasOwnProperty(prop)) {
console.log('Own property:', prop);
} else {
console.log('Inherited property:', prop);
}
}
// Output: Own property: type
// Output: Own property: make
// Output: Own property: model
// Output: Inherited property: start
לולאת for...in עוברת על כל המאפיינים הניתנים לספירה, כולל כאלה שנורשו. שימוש ב-hasOwnProperty() בתוך הלולאה מאפשר לסנן מאפייני prototype ולעבד רק את המאפיינים הישירים של האובייקט.
האלטרנטיבה המודרנית: Object.hasOwn()
ES2022 הציג את Object.hasOwn() כתחליף מודרני ל-hasOwnProperty(). המתודה עובדת באותו אופן אבל פותרת שני מקרי קצה שבהם hasOwnProperty() עלולה להיכשל.
למה Object.hasOwn() מומלצת
hasOwnProperty() יכולה להיכשל בשני מצבים:
- אובייקטים שנוצרו עם
Object.create(null)אין להם prototype, ולכןhasOwnProperty()לא קיימת עליהם. - אם אובייקט דורס את
hasOwnPropertyעם מאפיין משלו, קריאה ישירה תשתמש בגרסה הדרוסה במקום המקורית.
// Object.create(null) - אין שרשרת prototype
const config = Object.create(null);
config.debug = true;
// זה יזרוק שגיאה:
// config.hasOwnProperty('debug'); // TypeError
// Object.hasOwn() עובדת כמו שצריך:
console.log(Object.hasOwn(config, 'debug')); // true// hasOwnProperty דרוסה
const obj = {
hasOwnProperty: () => false, // דרוסה!
name: 'test'
};
console.log(obj.hasOwnProperty('name')); // false (לא נכון!)
console.log(Object.hasOwn(obj, 'name')); // true (נכון)Object.hasOwn() נתמכת בכל הדפדפנים המודרניים מאז 2022. עבור קוד חדש, העדיפו Object.hasOwn() על פני hasOwnProperty(). אם אתם צריכים לתמוך בסביבות ישנות, השיטה Object.prototype.hasOwnProperty.call(obj, prop) היא הפולבק הבטוח ביותר.
דוגמאות מעודכנות עם Object.hasOwn()
הנה הדוגמאות הקודמות כתובות מחדש עם התחביר המודרני:
const car = {
make: 'Toyota',
model: 'Corolla'
};
console.log(Object.hasOwn(car, 'make')); // true
console.log(Object.hasOwn(car, 'year')); // falseוסינון מאפיינים בירושה בלולאת for...in:
for (let prop in car) {
if (Object.hasOwn(car, prop)) {
console.log('Own property:', prop);
} else {
console.log('Inherited property:', prop);
}
}דוגמה חיה
בדוגמה אינטראקטיבית זו נראה כיצד hasOwnProperty() עובדת. הזינו שם מאפיין בשדה הקלט ולחצו על הכפתור כדי לבדוק אם הוא קיים ישירות באובייקט הדוגמה.
הפונקציה בודקת אם המאפיין שהוזן הוא מאפיין ישיר של האובייקט sampleObject ומציגה את התוצאה.
HTML:
<input type="text" id="propertyName" placeholder="Enter property name">
<button onclick="checkProperty()">Check Property</button>
<p id="result"></p>JavaScript:
const sampleObject = {
name: 'Sample',
value: 100
};
function checkProperty() {
const propName = document.getElementById('propertyName').value;
const hasProp = Object.hasOwn(sampleObject, propName);
document.getElementById('result').textContent = hasProp ?
`${propName} is an own property.` :
`${propName} is not an own property.`;
}תוצאה:
בדוגמה זו, הזנת "name" או "value" תחזיר true כי מאפיינים אלה מוגדרים ישירות על sampleObject. כל שם מאפיין אחר יחזיר false.
שאלות נפוצות
hasOwnProperty() בודקת רק מאפיינים ישירים של האובייקט. האופרטור in בודק גם מאפיינים ישירים וגם מאפיינים שנורשו משרשרת ה-prototype. לדוגמה, 'toString' in obj מחזיר true (בירושה מ-Object.prototype), בעוד ש-obj.hasOwnProperty('toString') מחזיר false.Object.hasOwn(). היא מטפלת במקרי קצה שבהם hasOwnProperty() נכשלת, כמו אובייקטים שנוצרו עם Object.create(null) או אובייקטים שדורסים את hasOwnProperty. היא נתמכת בכל הדפדפנים המודרניים מאז 2022 ומומלצת על ידי חוק ה-ESLint בשם prefer-object-has-own.hasOwnProperty() עובדת עליהם. אינדקסים של מערכים נשמרים כמפתחות מסוג מחרוזת, אז [10, 20, 30].hasOwnProperty('0') מחזיר true. המאפיין length גם מחזיר true כי הוא מאפיין ישיר של כל מערך. מתודות כמו push ו-map מחזירות false כי הן בירושה מ-Array.prototype.Object.create(null) יוצר אובייקט ללא prototype כלל - הוא לא יורש מ-Object.prototype. מכיוון ש-hasOwnProperty() מוגדרת על Object.prototype, קריאה אליה על אובייקט כזה זורקת TypeError. הפתרון הוא להשתמש ב-Object.prototype.hasOwnProperty.call(obj, prop), או פשוט להשתמש ב-Object.hasOwn(obj, prop) המודרנית.hasOwnProperty() לא הוצאה משימוש ועדיין עובדת בכל הדפדפנים. עם זאת, Object.hasOwn() (ES2022) היא האלטרנטיבה המודרנית המומלצת כי היא בטוחה ותמציתית יותר. חוק ה-ESLint בשם prefer-object-has-own מעודד מעבר ל-Object.hasOwn() בקודבייסים שתומכים ב-ES2022 ומעלה.סיכום
המתודה hasOwnProperty() היא כלי בסיסי לניהול מאפיינים באובייקטים ב-JavaScript, ומסייעת לכם להבחין בין מאפיינים ישירים של האובייקט לבין מאפיינים שנורשו משרשרת ה-prototype. עבור קוד חדש, העדיפו Object.hasOwn() כאלטרנטיבה בטוחה ותמציתית יותר.
הבנת אופן פעולת בעלות על מאפיינים תעזור לכם לכתוב קוד אמין יותר, במיוחד כשעוברים על אובייקטים עם for...in או עובדים עם נתונים דינמיים. כדי ללמוד על מבנה נתונים קרוב, עיינו במדריך למערכים ב-JavaScript.

