The output of console.log(anObject) is misleading; the state of the object displayed is only resolved when you expand the Object tree displayed in the console, by clicking on >. It is not the state of the object when you console.log'd the object.
Instead, try console.log(Object.keys(config)), or even console.log(JSON.stringify(config)) and you will see the keys, or the state of the object at the time you called console.log.
You will (usually) find the keys are being added after your console.log call.
The output of console.log(anObject) is misleading; the state of the object displayed is only resolved when you expand the Object tree displayed in the console, by clicking on >. It is not the state of the object when you console.log'd the object.
Instead, try console.log(Object.keys(config)), or even console.log(JSON.stringify(config)) and you will see the keys, or the state of the object at the time you called console.log.
You will (usually) find the keys are being added after your console.log call.
I've just had this issue with a document loaded from MongoDB using Mongoose.
When running console.log() on the whole object, all the document fields (as stored in the db) would show up. However some individual property accessors would return undefined, when others (including _id) worked fine.
Turned out that property accessors only works for those fields specified in my mongoose.Schema(...) definition, whereas console.log() and JSON.stringify() returns all fields stored in the db.
Solution (if you're using Mongoose): make sure all your db fields are defined in mongoose.Schema(...).
The usual way to check if the value of a property is the special value undefined, is:
if(o.myProperty === undefined) {
alert("myProperty value is the special value `undefined`");
}
To check if an object does not actually have such a property, and will therefore return undefined by default when you try to access it:
if(!o.hasOwnProperty('myProperty')) {
alert("myProperty does not exist");
}
To check if the value associated with an identifier is the special value undefined, or if that identifier has not been declared:
if(typeof myVariable === 'undefined') {
alert('myVariable is either the special value `undefined`, or it has not been declared');
}
Note: this last method is the only way to refer to an undeclared identifier without an early error, which is different from having a value of undefined.
In versions of JavaScript prior to ECMAScript 5, the property named "undefined" on the global object was writeable, and therefore a simple check foo === undefined might behave unexpectedly if it had accidentally been redefined. In modern JavaScript, the property is read-only.
However, in modern JavaScript, "undefined" is not a keyword, and so variables inside functions can be named "undefined" and shadow the global property.
If you are worried about this (unlikely) edge case, you can use the void operator to get at the special undefined value itself:
if(myVariable === void 0) {
alert("myVariable is the special value `undefined`");
}
I believe there are a number of incorrect answers to this topic. Contrary to common belief, "undefined" is not a keyword in JavaScript and can in fact have a value assigned to it.
Correct Code
The most robust way to perform this test is:
if (typeof myVar === "undefined")
This will always return the correct result, and even handles the situation where myVar is not declared.
Degenerate code. DO NOT USE.
var undefined = false; // Shockingly, this is completely legal!
if (myVar === undefined) {
alert("You have been misled. Run away!");
}
Additionally, myVar === undefined will raise an error in the situation where myVar is undeclared.
You can use the "short circuit" && operator:
if (myObject && myObject.myProperty) {
...
}
If myObject is "falsey" (e.g. undefined) the && operator won't bother trying to evaluate the right-hand expression, thereby avoiding the attempt to reference a property of a non-existent object.
The variable myObject must have course already have been declared, the test above is for whether it has been assigned a defined value.
You can use the optional chaining operator ?. to keep things succinct:
if (myObject?.myProperty) { ... }
which is equal to the a bit more verbose
if (myObject && myObject.myProperty) { ... }
It comes in very handy especially for deeply nested objects.
It's currently (September 2019) a ECMAScript stage 3 proposal but things are looking promising that this feature will become officially available. For the time being, you can already start using it via the respective Babel plugin: https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining
I've solved the problem. Basically, the object in question (that.data[0].cards) has its properties created by a function a() that runs after all the AJAX requests for the necessary XML files have been processed. I allow the requests to run asynchronously, using a counter to determine in the success callback function if a() should be called yet.
After a() runs, function b() is supposed to perform operations on that.data[i].cards. However, b() was running prior to a() being called because of a()'s reliance on the asynchronous requests. So the solution was simply to make a() call b().
So this turned out to be a pretty simple mistake on my part. What made it so confusing was the fact that logging that.data[0].cards to the console showed me that in fact the cards object had already been built, when in fact it had not yet. So the console was providing me with incorrect--or at least unclear--information.
Thanks for everyone's help last night! Upvotes all around :)
I think the object keys have unprintable characters, such can be replicated like this:
var obj = {};
obj["E"+String.fromCharCode(15)] = new Array(15);
console.log(obj);
/*Object
E: Array[15]
__proto__: Object*/
console.log(obj.E)
//undefined
console.log( obj["E"+String.fromCharCode(15)] )
//[]
Edit: you can see if this is the case for your object keys:
var realKeys = [];
for( var key in obj ) {
realKeys.push( [].slice.call( key ).map( function(v){return v.charCodeAt(0);} ).join(" ") );
}
//["69 15"] (69 stands for the letter "E" and 15 was the unprintable character I added manually)
Edit2: Since you can't do that I came up with another way to see if there are unprintable characters:
Copypaste the key string like this: (go all the way as much as you can on both ends so you pick any invisible characters)
Then dump your clipboard like this (Make sure you are using double quotes):
I don't understand why Javascript has to totally break when you try to access a property like object.property where object is undefined.
Say I'm using Vue and I'm displaying object.property on the screen. I have to add extra logic to make sure object is loaded (if it's async) because otherwise the whole page will break if it tries to display that before it has loaded in. Is there a better way of avoiding this problem? I feel like having
object != null ? object.property : null
all over the place is really a lot of extra boilerplate that shouldn't be necessary.