-7

It seems a solution for error message

TypeError: Cannot read property XXX of undefined

when using something like

if (item.property) {....}

is no longer valid. In fact, it seems even getting that error message is no longer possible because now you get

ReferenceError: item is not defined

I came across this because quite some time ago I had posted an accepted and 13 times upvoted answer to just such a question. I was not the only one giving the code that I gave as an answer, here is another one - same code, for the same type of problem. But those solutions now result in an error immediately!

I DID test my code, and if it had not worked it would hardly have been upvoted and accepted, same for the other Q/A I link to.

What is going on? I can't seem to provoke that error message (Cannot read property XXX of undefined) any more either, I tried by accessing a property of an undefined or a null variable. Have I gone mad, or has something else changed?

Community
  • 1
  • 1
Mörre
  • 5,699
  • 6
  • 38
  • 63

2 Answers2

2

No, this hasn't changed (there's something similar that's changed, but not this; more below). Here's the difference: If item isn't declared, then you'll get the error about item. If item is declared but has the value undefined, you'll get the error about reading a property of undefined. This has always been the case.

You mentioned Firefox. Firefox's error messages for these two different conditions are confusingly similar. If the variable is undeclared, it says:

ReferenceError: item is not defined

But if the variable is declared and has the value undefined, it says:

TypeError: item is undefined

Note the difference, but the extreme similarity. I would say Firefox's error messages are poor in this regard. Chrome's are more clearly distinct:

ReferenceError: item is not defined
TypeError: Cannot read property 'property' of undefined

But that's just the error message. The underyling issue, trying to read the value of an undeclared symbol, has always been an error.

Re the two answers you linked to: I'm sorry, but they were always wrong for the undeclared case (and right for the undefined case), this is just something that people don't understand well. If item may be completely undeclared, you can't use that idiom. You can use typeof, though:

if (typeof item !== "undefined" && item.property)

typeof is fine with undeclared symbols, but reading the value of an undeclared symbol is an error, as has been for as long as we've had JavaScript.

Here's a question from 2011 about this. The accepted answer with a score of 1,016 talks about typeof.

Here are examples of both cases:

Undeclared:

// Note that `item` isn't declared anywhere at all
try {
  if (item.property) {
    snippet.log("true");
  }
}
catch (e) {
  snippet.log((e.name || "Exception") + ": " + (e.message || String(e)));
}
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Declared but has the value undefined:

var item;
try {
  if (item.property) {
    snippet.log("true");
  }
}
catch (e) {
  snippet.log((e.name || "Exception") + ": " + (e.message || String(e)));
}
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

The similar thing that's changed is how assigning to something that isn't declared at all is handled:

item = "foo";

In loose mode, that's an implicit global variable, even if the assignment is inside a function. In ES5's strict mode, though, it's an error.

But that doesn't relate to reading the value of an undeclared variable, which was always an error, just writing to it.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Comments are not for extended discussion; this conversation has been [moved to chat](http://chat.stackoverflow.com/rooms/66563/discussion-on-answer-by-t-j-crowder-has-something-changed-in-javascript-impleme). – Taryn Dec 10 '14 at 11:20
-1

From the OP:

when using something like

if (item.property) {....}

is no longer valid. In fact, it seems even getting that error message is no longer possible because now you get

That is incorrect.
In both linked questions, the OPs mention item being undefined, which means they are declared, which means the answers, if (item && item.property), will work exactly as expected.

Nothing has changed in this regard, so to answer your question:

why things that worked don't work any more. I link to TWO answers that were accepted and highly upvoted that don't work (any more)!

Those answers work just fine. Unless you change the parameters of the question, which is what you're doing.
(You're assuming item is undeclared instead of undefined)

There's a difference between a typeof being "undefined" and the actual variable being undefined:

enter image description here

Community
  • 1
  • 1
Cerbrus
  • 70,800
  • 18
  • 132
  • 147
  • There's a difference between a `typeof` being `"undefined"` and the actual variable being `undefined`. Have a look at the screenshot I added. When an OP says `x is undefined`, I'm not assuming they mean `typeof x is "undefined"` – Cerbrus Dec 10 '14 at 08:33
  • `"undefined" !== undefined`. If those OP's _did_ think of using `tyepof`, they would have mentioned it. Besides, _both_ OP's state that `item.property` is `undefined`. This can _only_ be the case if `item` is declared. _That_ is why I'm claiming the variable _has_ to be declared. – Cerbrus Dec 10 '14 at 08:38
  • Heck, you even retracted your "This doesn't work" comment from [one of the questions you linked to in the OP.](http://stackoverflow.com/questions/8004617/javascript-cannot-read-property-bar-of-undefined) – Cerbrus Dec 10 '14 at 08:42
  • How is [the other question](http://stackoverflow.com/questions/5145164/javascript-if-not-undefined) not about object properties? – Cerbrus Dec 10 '14 at 08:46