Maison  >  Article  >  interface Web  >  Introduction à l'utilisation de Object.defineProperty en JS (exemple de code)

Introduction à l'utilisation de Object.defineProperty en JS (exemple de code)

不言
不言avant
2019-03-15 17:12:212278parcourir

Cet article vous présente une introduction à l'utilisation de Object.defineProperty dans JS (exemples de code). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

En JavaScript, les propriétés des objets sont souvent ajoutées ou modifiées via les méthodes suivantes :

obj.name = 'John'

De plus, les objets peuvent également être ajoutés ou modifiés via la méthode Object.defineProperty() propriétés. Plus important encore, en plus de l'objet cible obj et du nom de propriété prop, la méthode peut transmettre le descripteur de propriété pour obtenir des propriétés plus complexes. Un descripteur d'attribut est un objet et a deux formes : l'une est un descripteur de données et l'autre est un descripteur d'accès.

Object.defineProperty(obj, prop, descriptor)

Descripteur de données

Le descripteur de données prend en charge les fonctionnalités suivantes :

enumerable : indique si l'objet peut être énuméré. La valeur par défaut est false, ce qui signifie qu'elle ne peut pas être énumérée dans for...in et Object.keys(), et elle affecte également JSON.stringify().

configurable : indique si les attributs de l'objet peuvent être supprimés et si d'autres attributs, à l'exception des attributs de valeur et d'écriture, peuvent être modifiés. La valeur par défaut est false, ce qui signifie que l'attribut ne peut pas être supprimé et que les caractéristiques ne peuvent pas être modifiées.

valeur : La valeur correspondant à l'attribut, la valeur par défaut est indéfinie.

inscriptible : la valeur par défaut est false, ce qui signifie qu'elle est en lecture seule et ne peut pas attribuer de valeur à cette propriété. En mode strict, attribuer une valeur à une propriété en lecture seule entraînera une erreur. En mode détendu, l'attribution de valeurs aux propriétés en lecture seule ne prendra pas effet.

// 示例1,等同于 obj.name = 'John'
var obj = {}
Object.defineProperty(obj, 'name', { 
  value: 'John',
  writable: true,
  configerable: true,
  enumerable: true
})

// 示例2,将 name 属性设置为只读
'use strict'
var obj = {}
Object.defineProperty(obj, 'name', {
  value: 'John',
  writable: false,
  configerable: true,
  enumerable: true
})
obj.name = 'Joy'  // TypeError

// 示例3,将 name 属性设置为不可枚举
var obj = {}
Object.defineProperty(obj, 'name', { 
  value: 'John',
  writable: true,
  configerable: true,
  enumerable: false
})
console.log(obj.name)  // John
console.log(Object.keys(obj))  // []

// 示例4,将 name 属性设置不可配置(不可删除,除value和writable特性外的其它特性不可被修改)
var obj = {}
Object.defineProperty(obj, 'name', { 
  value: 'John',
  writable: true,
  configerable: false,
  enumerable: true
})
delete obj.name  // false
Object.defineProperty(obj, 'name', { enumerable: false })  // TypeError

Descripteur de stockage

Le descripteur de stockage prend en charge les fonctionnalités suivantes :

énumérable : identique à ci-dessus.

configurable : Idem que ci-dessus.

set : Définit la méthode setter. Lorsqu'un attribut est modifié, cette méthode sera exécutée avec la nouvelle valeur de l'attribut comme paramètre. La valeur par défaut n'est pas définie.

get : Définissez la méthode getter, qui sera exécutée lors de l'accès à la propriété. La valeur par défaut n'est pas définie.

// 示例5,使用 get 和 set,计数属性读写的次数
var obj = {}, name = '', count1 = 0, count2 = 0
Object.defineProperty(obj, 'name', { 
  get: function () { 
    console.log('Read ' + (++count1) + ' times')
    return name
  },
  set: function (newVal) {
    console.log('Write ' + (++count2) + ' times')
    name = newVal
  }
})
obj.name  // Read 1 times
obj['name']  // Read 2 times
obj.name = 'Joy'  // Write 1 times
obj.name = 'Jack'  // Write 2 times

Remarques

De plus, il y a trois points à noter : premièrement, les attributs avec deux descripteurs différents ne peuvent pas être partagés ; deuxièmement, lors de l'ajout d'attributs, les caractéristiques qui ne sont pas transmises ; sera défini sur La valeur par défaut, et lors de la modification des caractéristiques, les caractéristiques non introduites restent inchangées ; la troisième est la suivante :

Object.defineProperty(obj, 'name', { value: 'John' })
// 属性是只读,不可配置,且不可枚举的。等同于
Object.defineProperty(obj, 'name', { 
  value: 'John',
  writable: false,
  configerable: false,
  enumerable: false
})

obj.name = 'John'
// 属性可写的,可配置的,可枚举的。等同于
Object.defineProperty(obj, 'name', { 
  value: 'John',
  writable: true,
  configerable: true,
  enumerable: true
})

Application réelle

Par exemple, il y a un objet Étudiant, qui a deux attributs : nom et âge, que dois-je faire si je ne veux pas que l'âge soit trop élevé ou trop bas ? Nous pouvons ajouter une méthode setter et getter. Chaque fois que nous voulons modifier l'âge, nous pouvons modifier l'attribut via la méthode setter et lire l'attribut via la méthode getter :

function Student (name, age) {
  this.name = name
  this.setAge = function (val) { 
    age = val
    if (age < 0) age = 0
    if (age > 100) age = 100
  }
  this.getAge = function () { return age }
}

var s = new Student('John', 16)
s.setAge(25)
console.log(s.getAge())  // 25
s.setAge(-5)
console.log(s.getAge())  // 0
s.setAge(500)
console.log(s.getAge())  // 100

Cela semble beau, mais chaque fois qu'il est lu ou que la modification des propriétés nécessite d'appeler une fois la méthode setter ou getter, ce qui ajoute beaucoup de code. Grâce à la méthode Object.defineProperty, aucun code supplémentaire n'est nécessaire et les propriétés peuvent être lues et modifiées directement de la manière la plus primitive :

function Student (name, age) {
  this.name = name
  var _age = age
  Object.defineProperty(this, 'age', {
    get: function () { return _age },
    set: function (val) {
      _age = val
      if (_age < 0) _age = 0
      if (_age > 100) _age = 100
    }
  })
}

var s = new Student('John', 16)
s.age = 25
console.log(s.age)  // 25
s.age = -5
console.log(s.age)  // 0
s.age = 500
console.log(s.age)  // 100

Traitement par lots

Le Object.defineProperties( ) peut être ajoutée par lots Ou modifier les attributs :

var obj = {}
Object.defineProperties(obj, {
  name: { value: 'John', emunerable: true },
  age: { value: 20, emunerable: true }
})

La méthode Object.create() peut ajouter des attributs par lots lors de la création d'objets :

var obj = Object.create(Object.prototype, {
  name: { value: 'John', emunerable: true },
  age: { value: 20, emunerable: true } 
})

Vous pouvez également créer des setters et getters via des littéraux. Objet des attributs :

var obj = {
  get name() {
    return 'John'
  },
  set name(val) {
    console.log(val)
  },
  get age() {
    return 18
  }
}
.

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