1 votes

Comportement étrange de Object.defineProperty() en JavaScript

Je jouais avec le code javascript ci-dessous. Compréhension de Object.defineProperty() et je suis confronté à un étrange problème avec celui-ci. Lorsque j'essaie d'exécuter le code ci-dessous dans le navigateur ou dans le code VS, la sortie n'est pas celle attendue, alors que si j'essaie de déboguer le code, la sortie est correcte.

Lorsque je débogue le code et que j'évalue le profil, je peux voir le name & age dans l'objet Mais au moment de la sortie, il ne montre que la propriété name propriété

//Code Snippet 
let profile = {
  name: 'Barry Allen',
}

// I added a new property in the profile object.
Object.defineProperty(profile, 'age', {
  value: 23,
  writable: true
})

console.log(profile)
console.log(profile.age)

Maintenant, la sortie attendue ici devrait être

{name: "Barry Allen", age: 23}
23

mais j'obtiens le résultat suivant. Notez que je suis capable d'accéder à la age propriété définie par la suite. Je ne suis pas sûr de la raison pour laquelle le console.log() se comporte de cette façon.

{name: "Barry Allen"}
23

84voto

Maheer Ali Points 32926

Vous devez définir enumerable à true . Sur Object.defineProperty son false par défaut. Selon MDN .

énumérable

true si et seulement si cette propriété apparaît lors de l'énumération des propriétés de l'objet correspondant.

La valeur par défaut est false.

Non-énumérable signifie que la propriété ne sera pas montrée dans Object.keys() o for..in boucle ni dans la console

let profile = {
    name: 'Barry Allen',
}

// I added a new property in the profile object.

Object.defineProperty(profile , 'age', {
    value: 23,
    writable: true,
    enumerable: true
})
console.log(profile)
console.log(profile.age)

Toutes les propriétés et méthodes de prototype des classes intégrées ne sont pas dénombrables. C'est la raison pour laquelle vous pouvez les appeler depuis une instance mais ils n'apparaissent pas lors de l'itération.

Pour obtenir toutes les propriétés (y compris les propriétés non énumérables) Object.getOwnPropertyNames() .

let profile = {
    name: 'Barry Allen',
}

// I added a new property in the profile object.

Object.defineProperty(profile , 'age', {
    value: 23,
    writable: true,
    enumerable: false
})
for(let key in profile) console.log(key) //only name will be displayed.

console.log(Object.getOwnPropertyNames(profile)) //You will se age too

23voto

CertainPerformance Points 110949

Par défaut, les propriétés que vous définissez avec defineProperty ne sont pas énumérable - cela signifie qu'ils n'apparaîtront pas lorsque vous itérerez sur leurs noms de domaine. Object.keys (c'est ce que fait la console du snippet). (De même, la length d'un tableau ne s'affiche pas, car elle n'est pas dénombrable).

Voir MDN :

énumérable

vrai si et seulement si cette propriété apparaît lors de l'énumération des propriétés de l'objet correspondant.

La valeur par défaut est false.

Rendez-le énumérable à la place :

//Code Snippet 
let profile = {
  name: 'Barry Allen',
}

// I added a new property in the profile object.
Object.defineProperty(profile, 'age', {
  value: 23,
  writable: true,
  enumerable: true
})

console.log(profile)
console.log(profile.age)

La raison pour laquelle vous pouvez voir la propriété dans le image enregistrée est que la console de Chrome vous montrera également les propriétés non dénombrables mais les propriétés non dénombrables seront légèrement grisées :

enter image description here

Voir comment age est grisâtre, tandis que name ne l'est pas - cela indique que name est énumérable, et age ne l'est pas.

4voto

RK_15 Points 827

Chaque fois que vous utilisez la méthode ".defineProperty" d'un objet. Vous devez mieux définir toutes les propriétés du descripteur. Parce que si vous ne définissez pas d'autres propriétés du descripteur alors il suppose des valeurs par défaut pour toutes ces propriétés, ce qui est faux. Donc votre console.log vérifie toutes les propriétés énumérables : true et les enregistre.

//Code Snippet 
let profile = {
  name: 'Barry Allen',
}

// I added a new property in the profile object.
Object.defineProperty(profile, 'age', {
  value: 23,
  writable: true,
  enumerable : true,
  configurable : true
})

console.log(profile)
console.log(profile.age)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X