Maîtriser l'utilisation de Object.prototype.hasOwnProperty.call() en JavaScript

Dans de nombreux projets JavaScript, on rencontre souvent l'appel Object.prototype.hasOwnProperty.call(objet, 'propriete'). Décryptons ensemble ce pattern pour comprendre son importance et son fonctionnement.

L'essence de Object.prototype

L'héritage prototypique constitue un pilier fondamental de JavaScript, permettant aux objets de détenir des méthodes et propriétés via leur prototype. Considérons cet exemple :

const livre = {titre: 'Introduction à JS'};
livre.hasOwnProperty('titre'); // renvoie true

Bien que hasOwnProperty ne soit pas défini directement sur l'objet livre, son appel fonctionne grâce à la délégation via la chaîne de prototypes. En effet, tout objet littéral hérite de Object.prototype par défaut, comme le confirme :

Object.getPrototypeOf(livre) === Object.prototype; // true

La chaîne de prototypes pour cet objet suit ce schéma : livre → Object.prototype → null. On peut modifier cette chaîne à l'aide de Object.setPrototypeOf() ou Object.create(), comme dans cette illustration :

const vehicule = {roues: 4};
const protoVehicule = {demarrer() { return 'Moteur en marche'; }};

Object.setPrototypeOf(vehicule, protoVehicule);
vehicule.demarrer(); // 'Moteur en marche'

Le mécanisme d'emprutn de fonction

Lorsqu'on souhaite appliquer une fonction à un contexte différent, on exploite les méthodes call ou apply disponibles sur Function.prototype. Prenons une fonction et un objet :

function presenter() { console.log(`Je suis ${this.identifiant}`); }
const utilisateur = {identifiant: 'alice'};

Pour exécuter presenter avec le contexte de utilisateur, sans l'y lier définitivement, on utilise l'emprunt :

presenter.call(utilisateur); // 'Je suis alice'

Le premier argument de call spécifie la valeur de this pour l'appel.

Pourquoi préférer Object.prototype.hasOwnProperty.call ?

Considérons un scénario où un objet est créé avec un prototype nul :

const donnee = Object.create(null);
donnee.cle = 'valeur';

Tenter d'appeler driectement hasOwnProperty sur cet objet échoue :

donnee.hasOwnProperty('cle'); // TypeError: donnee.hasOwnProperty n'est pas une fonction

Cet échec survinet car la chaîne de prototypes ne contient pas la méthode, elle aboutit immédiatement à null. C'est ici que l'emprunt via Object.prototype.hasOwnProperty.call entre en jeu :

Object.prototype.hasOwnProperty.call(donnee, 'cle'); // true

Cette approche garantit la robustesse, notamment dans les bibliothèques où l'objet passé en argument pourrait avoir un prototype personnalisé ou absent. En évitant les erreurs de type, on assure la fiabilité du code.

En résumé, l'utilisation de Object.prototype.hasOwnProperty.call() contourne les limites imposées par les prototypes modifiés ou inexistants, assurant ainsi une vérification sûre des propriétés d'objet.

Étiquettes: JavaScript Object.prototype hasOwnProperty héritage prototypique méthode call

Publié le 9 juillet à 18h14