Maison  >  Article  >  interface Web  >  Explication détaillée des attributs de données et des attributs d'accesseur des objets JavaScript

Explication détaillée des attributs de données et des attributs d'accesseur des objets JavaScript

青灯夜游
青灯夜游avant
2020-07-09 15:00:042445parcourir

Explication détaillée des attributs de données et des attributs d'accesseur des objets JavaScript

Il existe deux manières de créer des objets : la première, via l'opérateur new suivi du constructeur Object, et la seconde, la méthode littérale d'objet. Comme indiqué ci-dessous

var person = new Object();
person.name = 'Nicy';
person.age = 21;
person.sayName = function() {
    console.log(this.name);
};        
var person = {
    name: 'Nicy',
    age: 21,
    sayName: function() {
        console.log(this.name);
    }
}

Les objets créés par ces deux méthodes sont les mêmes et ont les mêmes propriétés et méthodes. Ces propriétés possèdent des descripteurs de propriétés internes qui décrivent leur comportement.

Object.defineProperty()

En utilisant Object.defineProperty(), vous pouvez directement créer une propriété sur l'objet, ou vous pouvez modifier la propriété existante.

Object.defineProperty(obj, prop, descriptor) reçoit trois paramètres :

obj : l'objet où se trouve l'attribut

prop : le nom de l'attribut auquel accéder

Descripteur : Objet descripteur

L'objet descripteur contient six attributs : configurable, énumérable, inscriptible, value, get, set. Pour modifier les caractéristiques des attributs, vous devez utiliser le Object.defineProperty(. ) méthode.

La valeur par défaut de la propriété booléenne des propriétés d'objet ajoutées via les deux méthodes ci-dessus est vraie. Lors de la modification des propriétés de propriété via Object.defineProperty, définissez uniquement les propriétés qui doivent être modifiées et ; via Object La propriété créée par .defineProperty possède un attribut booléen dont la valeur par défaut est false.

Il existe deux types d'attributs dans ECMAScript : les attributs de données et les attributs d'accesseur.

Attribut de données

L'attribut de données contient quatre descripteurs d'attribut :

[[Configurable]] : indique si redéfinir la propriété en le supprimant via delete. Les propriétés de la propriété peuvent-elles être modifiées ? La propriété peut-elle être modifiée en propriété d'accesseur ? Les propriétés de l'objet ajoutées via la méthode ci-dessus sont par défaut true.

[[Enumerable]] : Indique si l'attribut est accessible via la boucle for-in. Les attributs d'objet ajoutés via la méthode ci-dessus sont par défaut true.

[[Writable]] : Indique si la valeur de l'attribut peut être modifiée. Les attributs d'objet ajoutés via la méthode ci-dessus sont par défaut true.

[[Valeur]] : Contient la valeur des données de cet attribut, qui peut être lue et écrite. Les propriétés de l'objet ajoutées via la méthode ci-dessus sont par défaut non définies.

Writable

var person = {};

Object.defineProperty(person, "name", {
    value: 'Nicy'
})
person.name = 'Lee';  
console.log(person.name)    // 'Nicy'

Object.defineProperty(person, "name", {
    writable: true
})
person.name = 'Lee';
console.log(person.name)    // 'Lee'

La propriété inscriptible créée directement par Object.defineProperty est par défaut false et la valeur ne peut pas être modifiée pour le moment, changez le nom en Lee, qui ne fonctionne pas en mode non strict, une erreur sera signalée, mais l'opération sera ignorée. En mode strict, une erreur sera signalée.

Configurable

<span style="font-size: 13px;"><span style="color: #0000ff;"></span>var person = {<br>    name: 'Nicy',<br>    age: 21,<br>    sayName: function() {<br>        console.log(this.name);<br>    }<br>}<br><br>Object.defineProperty(person, "name", {<br>    configurable: false<br>})<br><br>delete person.name;    // 操作被忽略,无法通过delete删除属性<br>Object.defineProperty(person, "name", {    // throw error<br>    configurable:true    <br>})     <br>Object.defineProperty(person, "name", {    // throw error<br>    enumerable: false<br>})  <br>Object.defineProperty(person, "name", {     // 由于writable为true,所以可以修改value<br>    value: 'Lucy'<br>})console.log(person.name)    // Lucy<br>Object.defineProperty(person, "name", {    // writable可进行true -> false的单向修改<br>    writable: false<br>})<br>Object.defineProperty(person, "name", {     // throw error<br>    value: 'Lee'<br>})<br>Object.defineProperty(person, "name", {    // throw error,此时writable不可以false -> true<br>    writable: true<br>})<span style="color: #000000;"></span></span>

Pour résumer le configurable : lorsque configurable est défini sur false,

1. Vous ne pouvez pas supprimer l'attribut via delete pour le redéfinir Propriétés ;

2. Ne peut pas être converti en propriétés d'accesseur ;

3. Configurable et énumérable ne peuvent pas être modifiés

4. inscriptible peut être modifié dans une direction ; comme faux, mais ne peut pas être changé de faux à vrai;

 5. La possibilité de modifier la valeur dépend de l'écriture.

Lorsque configurable est faux, utilisez delete pour supprimer l'attribut. En mode non strict, aucune erreur ne sera signalée, mais l'opération est ignorée. En mode strict, une erreur sera signalée lorsque d'autres fonctionnalités sont signalées. ne peut pas être modifié, une erreur sera signalée.

Enumerable

enumerable indique si les propriétés de l'objet peuvent être énumérées dans for...in et Object.keys().

var person = {};
Object.defineProperty(person, "a", { value : 1, enumerable:true });
Object.defineProperty(person, "b", { value : 2, enumerable:false });
Object.defineProperty(person, "c", { value : 3 }); // enumerable defaults to false
person.d = 4; // 如果使用直接赋值的方式创建对象的属性,则这个属性的enumerable默认为true

for (var i in person) {    
  console.log(i);  
}  //  'a' 和 'd' 

Object.keys(person); // ["a", "d"]

Propriétés de l'accesseur

Les propriétés de l'accesseur contiennent quatre descripteurs de propriété :

[[Configurable]] : Indique si l'attribut peut être redéfini en supprimant l'attribut via la suppression, si les caractéristiques de l'attribut peuvent être modifiées et si l'attribut peut être modifié en attribut de données. Les propriétés définies directement sur l'objet sont par défaut true.

[[Enumerable]] : Indique si l'attribut est accessible via la boucle for-in. Les propriétés définies directement sur l'objet sont par défaut true.

[[Get]] : Fonction appelée lors de la lecture des propriétés, la valeur par défaut n'est pas définie.

[[Set]] : Fonction appelée lors de l'écriture des propriétés, la valeur par défaut n'est pas définie.

var person = {
    name: 'Nicy',
    _age: 21,
    year: 1997,
    _year: 1997,
    sayName: function() {
        console.log(this.name);
    }
}

Object.defineProperty(person, "age", {
    get: function() {
        return this._age;
    },
    set: function(value) {
        this._age = value;
                // ...
    }
})

Propriétés d'accesseur définies avec Object.defineProperty(), leur valeur par défaut configurable et énumérable est false.

Conversion entre les attributs de données et les attributs d'accesseur

Propriétés Object.getOwnPropertyDescriptor pour la lecture des propriétés

Utilisez Object.getOwnPropertyDescriptor pour obtenir le descripteur de propriété :

Object.getOwnPropertyDescriptor(obj, prop)

obj : l'objet où se trouve la propriété

Prop ; : le nom de la propriété à laquelle accéder.

Attribut de données-> Attribut d'accesseur

L'attribut ne peut être qu'un descripteur d'accesseur et un descripteur de données, pour les données existantes Lorsqu'une propriété plus get ou set est convertie dans une propriété d'accesseur, la valeur et l'écriture de sa propriété seront ignorées.

Le code suivant convertit l'année de l'attribut de données d'origine de l'objet en un attribut accesseur :

*Remarque : dans le get et le set de l'attribut accesseur, cela ne peut pas être utilisé pour access La propriété elle-même, sinon une récursivité infinie se produira et provoquera des fuites de mémoire.

// 设置get和set其中任意一个即可转换为访问器属性
Object.defineProperty(person, "year", {
    get: function() {
//        return this,year;    // error
        return this._year;    
    },
    set: function(value) {
//             this.year = value;  // error
        this._year= value;
    }
})

var descriptor = Object.getOwnPropertyDescriptor(person, 'year');
console.log(descriptor);    // {get: ƒ, set: ƒ, enumerable: true, configurable: true}

Au cours de l'année d'attribut de données d'origine, utilisez Object.defineProperty() pour définir get ou set pour l'attribut, qui peut être converti en attribut accesseur.

Propriétés de l'accesseur -> Propriétés des données

将访问器属性转换为数据属性,只需要给现有访问器属性设置value或writable这两个属性描述符中的任意一个即可,其原有的get和set就会被废弃,从而转换为数据属性。

上面为person定义的访问器属性age,通过Object.defineProperty()只设置了get和set,所以configurable默认为false,不可以将其转换为数据属性。可以在访问器属性和数据属性间相互转化的属性其configurable特性值必须为true。

如下代码,我们为person新定义一个访问器属性job,将其configurable设置为true ,并将其转换为数据属性:

Object.defineProperty(person, "job", {
    configurable: true,
    enumerable: true,
    get: function() {
        return this._job;
    },
    set: function(value) {
        this._job = value;
    }
})

// 设置value和writable其中任意一个即可转换为数据属性        
Object.defineProperty(person, "job", {
    value: 'worker',
    writable: true
})

var descriptor = Object.getOwnPropertyDescriptor(person, 'job');
console.log(descriptor);    // {value: "worker", writable: true, enumerable: true, configurable: true}

数据描述符value、writable 和访问器描述符get、set不能同时设置,否则会报错。

Object.defineProperties()

通过Object.defineProperties()可以一次性为对象定义多个属性。

var person = {};
Object.defineProperties(person, {
  name: {
    value: 'Nicy',
    writable: true
  },
  _age: {
    value: 21,
    enumerable: true,
    writable: true,
    configurable: true
  },
   age: {
    get: function() {
    return this._age;
    },
    set: function(value) {
    this._age = value;
    }
  }
});

 相关教程推荐:JavaScript视频教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer