var a = window.a || {};
It means a will be assigned window.a if it is not null or undefined, otherwise, it will equal an empty object
To answer the unasked question: this is used to make sure "a" will be valid.
Without it, when calling a.someFieldHere you might get exception saying "a is undefined", with such code in place you won't get such error.
It's useful when "a" is created elsewhere in some other code that not always get executed.
Kind of insurance policy. :)
Related
I'm using an AdMob plugin in my Ionic application, and one way, as you can see in the documentation, to test if the plugin is properly loaded is to do:
if(AdMob) {
///other config code...
}
Now, this works perfectly fine on a device. However, it doesn't work in the browser; it throws an error in the console log: AdMob is not defined.
I have found a solution to test the existence of plugin like this (without throwing an error in the console):
if (window.AdMob){...}
And I have seen this usage on multiple questions here on StackOverflow. However, I wasn't able to find an explanation to as why this doesn't throw an error.
I have a vague reasoning to as why this would be so, but I would really appreciate it if someone experienced could explain it in more detail.
edit: I made additional tests like this:
var a = "hi";
console.log(a); //shows "hi"
console.log(b); //throws an error that b is not defined
var c = {};
c.b = "hi again";
console.log(c.b); //shows "hi again" as expected
//and now for the grand finale
console.log(c.something);//doesn't throw an error, please explain to me in more detail why?
I wasn't able to find an explanation to as why this doesn't throw an error.
In the first example, you're trying to read the value of a completely undefined identifier. In the second example, you're trying to read a property from an object that the object may not have.
Trying to read the value of an undefined identifier is a ReferenceError; the JavaScript engine has no idea what that identifer is. In contrast, trying to read the value of a property that the object doesn't have yields the value undefined.
It's just how the language is designed, where Brendan Eich drew the line: It's okay to read the value of a non-existant property from an object, but not okay to read the value of an undeclared identifier.
I should point out a third option: typeof. You're allowed to provide an undefined identifier as the operand to typeof:
if (typeof AdMob === "undefined")
That won't throw a ReferenceError even if AdMob is undeclared; instead, typeof will yield "undefined". (It will also yield "undefined' if AdMob is a declared identifier with the value undefined in it.)
In a comment on another answer, you said:
...it would just indeed help to see the exact official specification which confirms this.
That would be the ECMAScript specification, specifically §6.2.3.1 for throwing a ReferenceError on an unresolvable symbol, and §9.1.8 for returning undefined for a property that doesn't exist. But I should warnin you that the spec, especially this 6th edition spec, is very heavy going. :-)
Common practice when checking whether a variable is undefined in JavaScript is as follows:
var isUndefined=(typeof variableName==="undefined");
I've recently come across the use of two exclamation symbols to determine the same logic:
var isUndefined=!!variableName;
Is it safe to use these methods interchangeably?Are both equally compatible across browsers?
Is there any reason why one shouldn't use the "!!" method? (It seems more concise and easy to read)
Is it safe to use these methods interchangeably?
No. Details below, but they're not interchangeable even if you remove one of the ! from your second example (with two of them, it will be true for undefined, which isn't what you seem to want from the name of the variable you're assigning to). But that's not the only issue.
Are both equally compatible across browsers?
Yes. Each of them works reliably across browsers. But see above: They reliably don't do the same thing.
Is there any reason why one shouldn't use the "!!" method?
Yes, ! (again, not !!) gives the same result for 0, NaN, null, "", and false as it does for undefined.
Details:
When you do
var isUndefined = typeof variableName==="undefined";
(the () are unnecessary), you're doing a very specific test for undefined. It will only be true for undefined.
In contrast, when you do
var isUndefined = !variableName;
you're not testing for undefined, you're testing for any falsey value. The falsey values are the ones I listed earlier (0, NaN, null, "", false, and undefined). The result will be true for any of them.
Now, if you're expecting (for instance) to get a non-null object reference or undefined, the ! test is just fine. But if you really need to know whether something is undefined, specifically, you want the typeof test.
Also, as Felix Kling pointed out in a comment on the question, the ! test will throw a ReferenceError if the variable isn't defined at all (as opposed to being defined but having the value undefined), because it tries to read the value of the variable. The typeof test is safe if you're not sure whether the variable exists at all, because it doesn't try to read its value.
I’ve been reading about undefined in JavaScript and now I am not sure if my understanding is correct. There is a lot of talk around how to check for undefined but somehow I couldn’t find any mentioning of something that to me seems fundamental to understanding of how undefined actually works (undefined being property on host object). This is the reason for this question, I need to confirm that what I understand is correct and if I’m wrong I would appreciate clarification.
Okay, first of all, undefined is property on host object (window in browsers) so it’s perfectly legal to use:
window.undefined
The value of this property is type "undefined". This is one of the JavaScript types along with Object, String, Number and Null. So if I do:
if(someVar===undefined) {}
I’m actually checking against window.undefined property, whatever it contains, is that right?
So this code below would be pretty dumb as this would check someVar only against the string "undefined", not the type nor the property of the window object, right?
if(someVar==='undefined') {}
This below would be also incorrect as this would check against the window.undefined property (whatever it contains):
if(typeof someVar===undefined) {}
So, to sum it up, the only proper and cross-browser way to check for undefined is to use typeof e.g.:
if(typeof someVar==='undefined')
Is that right?
Also in ES5 window.undefined cannot be reassigned but it’s perfectly legal in older browsers right?
This however can still be done and is evil if my understanding is right:
(function() {
var undefined=66;
alert(undefined);
})()
I would appreciate clarification if I misunderstood how undefined works in JavaScript.
You're almost correct. Except for this:
The value of [window.undefined] is type "undefined". This is one of Javascriupt types along with Object, String, Number, and Null
There are 3 undefined in javascript. The global variable undefined, the value undefined and the type undefined.
Even if the global variable undefined is overridden, the value undefined still exists. There are several ways to get it one of which is an empty argument to a function, another is a variable declaration without assigning anything:
// Note: Probably need older browsers to assign to undefined:
window.undefined = 1;
(function(foo){ // the value of foo is undefined;
var bar; // the value of bar is undefined;
return [foo === bar, foo === window.undefined]; // returns [true,false]
})();
Note carefully that in the example above we're checking the value, not the type. Yes === checks type and value but if you replace === with == the result would be the same.
The value undefined has type undefined ('Undefined' in the spec and documentation but typeof returns 'undefined') and type undefined is only valid for the value undefined.
That's all fine, plus:
you can use void 0 to reliably "generate" the real undefined value (or not-a-value; it's kind-of zen)
in a function, you can reference an argument that you know isn't supplied to get a reliable undefined
(function( undefined ) {
// ...
})();
This second example is not really the clearest code in the world, but you'll see it sometimes in common public codebases, tutorials, etc.
So if I do:
if(someVar===undefined) {}
I'm actually checking against window.undefined property whatever it
contains is that right?
Right.
So this code below would be pretty dumb as this would check someVar
only against the string undefined, not the type nor the property of
window object right?
if(someVar==='undefined') {}
Right.
This below would be also incorrect as this would check against the
window.undefined property (whatever it contains):
if(typeof someVar===undefined) {}
Right.
So to sum it up, the only proper and cross-browser way to check for
undefined is to use typeof e.g.:
if(typeof someVar==='undefined')
Is that right?
Yes, though it is error-prone because you may mis-type that string and get no error (even in strict mode) to indicate the mistake.
So it's better to call some method, especially if you're already using some framework e.g. in AngularJS - angular.isUndefined
Also in ES5 window.undefined cannot be reassigned but its perfectly legal in older browsers right?
Right.
This however can still be done and is evil if I my understanding is
right:
(function() {
var undefined=66;
alert(undefined);
})()
I believe so.
So to sum it up, the only proper and cross-browser way to check for undefined is to use typeof e.g.:
if(typeof someVar==='undefined')
No, the direct comparison somevar === undefined is fine.
There are any number of global variables that can be overwritten or shadowed that will break code. There's no way to protect against them all, except to simply not allow bad code.
What's nice about the direct comparison (aside from being shorter and cleaner) is that it's must more natural and intuitive, whereas people often get the other syntax wrong. They end up accidentally using the other examples you gave:
if (somevar === 'undefined')
if (typeof somevar === undefined)
These are very common errors, and are much more common than people redefining undefined.
Furthermore, you'll see things like this:
if (typeof somevar === 'undefiend')
This is much more subtle, and is hard to spot when surrounded by a bunch of other code. Again, it's a common mistake.
Probably the worst is when you see this:
if (typeof somevar === 'undefined')
somevar = "foobar";
What's wrong with that? Well, if somevar had not been declared, we've now created an implicit global variable. This can be really bad. If we had done a simple comparison, we would have been alerted to the problem with a ReferenceError.
like
function myFunction(){
var undefined = "abc";
}
If its possible then how to restrict not to allow that?
Is it possible to overwrite the undefined in javascript?
If by "the undefined" you mean the global undefined variable, then no. Since EcmaScript 5, it is specified as non-writable. However, older browsers don't adhere that spec, so it is overwritable in legacy engines. You cannot really prevent it in them, but always reset it by undefined = void 0;. If you still worry and want to know how to protect your own scripts, check the question How dangerous is it in JavaScript, really, to assume undefined is not overwritten?.
like function myFunction(){ var undefined = "abc"; }
That's a different thing. You can always declare a local variable with the name undefined (shadowing the global one) and assign arbitrary values to it.
Some browsers allow it, the best way to restrict it is avoiding it.
But... some are using this technique to preserve the undefined:
(function(undefined){
})()
They get a variable called undefined but don't pass a value which gives undefined the undefined value.
From jQuery's source code:
(function( window, undefined ) {
...
...
})(window);
Yes it is possible to overwrite undefined.
This question has good solutions for working around that problem - How to check for "undefined" in JavaScript?
Generally, I test whether or not a variable is set with something like this:
if (variable !== '') {
do something...
}
I know there are other methods for testing variables like typeof but I don't see any advantage - is this an appropriate way to test whether or not a variable is set? Are there problems with it that I should be aware of ?
Two reasons:
1) What if the variable is set by getting the contents of an empty input box?
if(someScenario){
var variable = $('empty-box').val(); }
Perhaps this is only done in certain cases, like when someScenario is true. Later on, you want to check if that variable was set. Your means returns false rather than true. Point is, you can come up with scenarios where you get wrong answers.
There's just no reason not to do it the accepted way.
if(typeof variable !== 'undefined')
It's no slower, has no real flaws, and is only a few characters more.
2) And most importantly, using typeof makes it totally clear what you're asking. Readability is crucial, and if another programmer read the first code, they would think you were checking that it wasn't an empty string. The method using typeof makes it perfectly clear what your conditional is looking for, and reduces the odds of mistakes later on.
If variable has been declared but might not have a value then your code:
if (variable !== '') {
tests if it is not the empty string. Is that what you want? An empty string might be a valid value. Better to test for undefined, or explicitly initialise it to a value that you can then treat as "invalid" (perhaps null, or whatever suits).
If variable has not been declared at all the above code would result in an error such that execution would stop at that point - you can't test the value of a variable that doesn't exist. So if, for example, you're trying to test a global variable that is created inside a function that may not have been called yet, or perhaps you're using several JS files and one needs to test a variable that may or may not have been created by one of the other files, then the only way to do it is with:
if (typeof variable != "undefined") {
Since you're using strict equality testing, the following will all return true:
false
undefined
null
0
The only time your check will return false is when you pass in an empty string.
Is that what you want?
Check out coffeescript's existential operator, by searching "The Existential Operator" on this page: http://coffeescript.org/
The functional problem with your approach is that is that you may inadvertently assign a blank string to variable at some point prior in your script and your logic block will now do the wrong thing.
From a stylistic standpoint your solution is less desirable because your intent to check the existence of the variable is not clear. Someone who was just reading through your code for this the first time might misunderstand what you wrote to mean "I'm expecting there to be a variable named variable set to the blank string" as opposed to "Do something if this variable does not exist."
This might be highly subjective, but my recommendation is to avoid code, that needs to check, whether a variable is set (a.o.t. has some value or type).
Consider this snipplet
var a=false;
if (some_condition) a="Blah";
if (typeof(a)=='string') ....
if (a===false) ...
this makes sure, a is always set, while keeping it easily differentiable from '', null or 0