3

If I open my JavaScript console (F12 on Chrome) and define a variable var x = {}; and then type x in the console it shows me an empty object like this: {}. So far so good.

If try to see x.a the console will give me undefined, and if I explicitly test x.a === undefined it gives true. So far so good.

Everything is telling me that the value of x.a is undefined.

So, since its value is undefined, I now execute a command that I was expecting to do absolutely nothing: x.a = undefined;. I thought this shouldn't change anything.

But now if I put x in the console, it shows {a: undefined} instead of {}. This is an evidence that something changed...

1. What is happening here?

2. Is there any situation in which this would make a difference?

3. If yes, how can I make that object go back to its initial state?

Note: of course, for question 3, re-assigning to a new {} is obviously not an option, since it would no longer === to the previous value.

Pedro A
  • 3,989
  • 3
  • 32
  • 56
  • **You got good answers down below, but I'm going to address that last note you added**: remember that object literals will never be equal to other object literals, except the ones that reference that same literal object. For example, doing `{} === {}` returns `false`, but doing ```var a = b = {}; a === b;``` turns out to be `true` – GMaiolo Nov 01 '17 at 23:12
  • 1
    @GMaiolo, thanks, I know, that's exactly why I said that re-assigning to a new {} is not an option. – Pedro A Nov 01 '17 at 23:14
  • 1
    I was adding the clarification to your note just in case someone that does not know that happens to read this question. – GMaiolo Nov 01 '17 at 23:19

3 Answers3

4

1. What is happening here?

At first you are accessing a non-existing property. That will always return undefined as defined in the language specification.

But a property can also exist and have the value undefined, which is what you are getting when doing

x.a = undefined;

This creates the property a on x and assigns the value undefined to it.

2. Is there any situation in which this would make a difference?

Testing the existence of the property would result in false in the first case and true in the second case.

var x = {};
console.log('a exists', 'a' in x);

x.a = undefined;
console.log('a exists', 'a' in x);

The value of the property is irrelevant when testing for existence.

Similarly, getting all properties of an object would yield different results:

var x = {};
console.log(Object.keys(x));

x.a = undefined;
console.log(Object.keys(x));

3. If yes, how can I make that object go back to its initial state?

You can delete properties using the delete operator:

delete x.a;
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
2

JavaScript treats the setting of a property to any value as a meaningful thing. The in operator illustrates:

var x = {};
console.log("a" in x); // false
x.a = undefined;
console.log("a" in x); // true

The in operator is the solid way to test whether a particular key is present in an object regardless of value. There's also the Object.hasOwnProperty() function if it matters that the property be directly present on the object.

If you want to get rid of a property completely, you can use delete:

delete x.a;
console.log("a" in x); // false

The undefined "value" (is it really a value?) is essentially a wart on the design of JavaScript; it makes it such that the language has effectively two null values. I understand why it's there, but that doesn't make the situation any easier to deal with.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • 1
    *"is it really a value?"* According to the language specification yes :) – Felix Kling Nov 01 '17 at 23:10
  • @FelixKling well sure, but there's something odd about it nevertheless! – Pointy Nov 01 '17 at 23:20
  • 2
    I absolutely agree with that :D I teach a JavaScript class where I work and I always say to not *create* `undefined` values in your own code (it's fine to use it for comparison) and only use `null` to express the "absence of a value". Only let the language use `undefined` to tell you something is missing. (you know all that already, but hopefully this is useful for other visitors). – Felix Kling Nov 01 '17 at 23:25
0

You can remove the key like so:

delete x.a;

Jim Cote
  • 1,746
  • 3
  • 15
  • 26