Le descripteur d'attribut est un nouveau concept ajouté dans ES5, et sa fonction est d'ajouter plus de contrôle aux propriétés de l'objet.
Objet.defineproperty
Pour étudier les descripteurs d'attribut, nous devons d'abord parler de la méthode object.defineproperty. Le but de cette méthode est de définir de nouvelles propriétés pour l'objet ou de modifier les propriétés existantes. Le prototype est le suivant:
La copie de code est la suivante:
Object.defineproperty (obj, prop, descripteur)
Exemple d'utilisation:
La copie de code est la suivante:
var obj = {};
Object.defineProperty (obj, 'attr', {valeur: 1});
Le code ci-dessus ajoute un attribut nommé att à l'objet OBJ, avec une valeur de 1. Équivalent à:
La copie de code est la suivante:
var obj = {};
obj.attr = 1;
En comparaison, l'écriture de l'objet.DefineProperty semble être plus compliquée. Cependant, son plus grand secret réside dans son troisième paramètre.
Descripteur de données
En supposant que nous voulons que ARTS soit un attribut en lecture seule, nous pouvons ajouter le descripteur de données écrits:
La copie de code est la suivante:
var obj = {};
Object.defineproperty (obj, 'att', {
Valeur: 1,
Écrivable: faux
});
console.log (obj.attr);
obj.attr = 2; // échouer
console.log (obj.attr);
Exécutez le programme ci-dessus et vous constaterez que la valeur d'ATRM imprimée deux fois est 1, ce qui signifie que l'écriture de l'attribut a échoué. Cependant, ce résultat sera un peu inexplicable, car l'exécution de l'instruction Affectation n'a pas d'exceptions, mais elle échoue. Imaginez simplement que si un tel problème se produit dans le code à succès, il sera difficile de le dépanner. En fait, tant que le code est exécuté en mode strict, une exception sera générée:
La copie de code est la suivante:
«utiliser strict»; // Entrez le mode strict
var obj = {};
Object.defineproperty (obj, 'att', {
Valeur: 1,
Écrivable: faux
});
obj.attr = 2; // lancer une exception
Jetons un coup d'œil à un autre descripteur de données énumérable, qui peut contrôler si l'attribut peut être énuméré. Si vous définissez simplement une propriété, cette propriété peut être énumérée dans le pour ... en boucle:
La copie de code est la suivante:
var obj = {};
obj.attr = 1;
pour (var i dans obj) {console.log (obj [i]); }
Énumérable peut le "cacher":
var obj = {};
Object.defineproperty (obj, 'att', {
Valeur: 1,
Énumérable: faux
});
pour (var i dans obj) {console.log (obj [i]); }
Exécutez le code ci-dessus et vous constaterez que la console ne produit rien, car l'attribut d'attribue ne peut pas être énuméré pour le moment.
Cela dit, vous pouvez avoir une question: le descripteur d'attribut peut-il être modifié? Par exemple, une propriété en lecture seule peut-elle être définie à nouveau comme écrivable? En fait, cela dépend d'un autre descripteur de données configurable, qui peut contrôler si le descripteur d'attribut peut être modifié.
La copie de code est la suivante:
var obj = {};
Object.defineproperty (obj, 'att', {
Valeur: 1,
Écrivable: faux,
configurable: vrai
});
Object.defineproperty (obj, 'att', {
Écrivable: vrai
});
obj.attr = 2;
Le code ci-dessus définit d'abord ARTH comme un attribut en lecture seule, puis le redéfinit en écriture. Donc, l'écriture à ATR est réussie.
Descripteur d'accès
Le descripteur d'accès est similaire à l'accessoire GET / SET dans les objets orientés objet.
La copie de code est la suivante:
var obj = {};
Object.defineproperty (obj, 'att', {
set: function (val) {this._attr = math.max (0, val); },
get: function () {return this._attr; }
});
obj.attr = -1;
console.log (obj.attr); // 0
Dans le code ci-dessus, l'accès à ARRT devient réellement l'accès à _ATTR, et la valeur minimale est limitée à 0 dans la fonction SET.
Obtenir un descripteur d'attribut
Les descripteurs d'attribut mentionnés ci-dessus sont-ils tous, alors comment obtenir les descripteurs définis? Object.getownpropertyDescriptor peut le faire.
La copie de code est la suivante:
var obj = {};
Object.defineproperty (obj, 'att', {
Valeur: 1,
Écrivable: faux,
configurable: vrai
});
var desc = object.getownPropertyDescriptor (obj, 'att');
Console.dir (DESC);
Contrôle des objets
L'objet.DefineProperty mentionné précédemment fonctionne sur les propriétés de l'objet, tandis que les trois méthodes mentionnées ci-dessous fonctionnent directement sur l'objet.
Object.preventextensions peut empêcher les objets d'avoir de nouvelles propriétés:
La copie de code est la suivante:
var obj = {};
obj.attr = 1;
Object.preventextensions (obj);
obj.attr2 = 2; //échouer
Object.Seal peut rendre l'objet uniquement des valeurs de propriété laissé à modifier (si la propriété est en lecture seule, même les valeurs de propriété ne peuvent pas être modifiées):
La copie de code est la suivante:
var obj = {};
obj.attr = 1;
Object.seal (obj);
obj.attr = 1,5;
supprimer obj.attr; // échouer
Object.freeze peut rendre les objets complètement non modifiés:
La copie de code est la suivante:
var obj = {};
obj.attr = 1;
Object.freeze (obj);
obj.attr = 1,5; // échouer
obj.attr2 = 2; //échouer
Ensuite, vous pouvez demander à nouveau, comment savez-vous si un objet a été empêché, sceller ou geler? La réponse est d'appeler Object.isextenible, object.isaled et object.isfrozen respectivement. L'utilisation de ces trois fonctions est relativement simple et plus lourde.
En général, l'objet peut être encore strictement contrôlé via des descripteurs d'attribut et la rigueur de la logique du programme est renforcée. Le seul inconvénient est que l'ES5 est essentiellement mis en œuvre dans IE9 (IE9 ne prend pas encore en charge le mode strict). Étant donné que la part de l'IE8 nationale est encore relativement élevée, cet ensemble de choses ne peut être utilisé que dans les navigateurs mobiles et Node.js.