As you see,undefined is not a keyword in javascript(Is it right?).So we can use it as a variable though I'm sure this is a bad idea.Now my question is why I can't give a value to undefined.
Code:
var undefined=3;
undefined;//still undefined
Any suggestions will be thankfull.
Because in older environments(before JS 1.8.5) it was possible to change the value of undefined, and checking for something that didn't exist was made in a way that was possible to break. It is a common choice to develop libraries inside their own closures, using the IIFE pattern to create a variable undefined which is not touched from external code(jQuery for example, and most libraries), this is an example:
(function(undefined) {
//code which safely uses undefined
})();
Note that there is a parameter called undefined and the IIFE is invoked without any parameter, making that undefined effectively become undefined. In newer environments it is not possible to change the value of undefined, but for retrocompatibility it is yet used a lot.
Yet the safest way to check for an undefined type is to use typeof. Its usage, in fact, cannot be overridden in any way, and it can be used safely: typeof foo == 'undefined'.
Remember that there is a slight difference between undefined and undeclared:
var x; //declared but undefined
x === undefined; //true
But in older environments you were able to do
var undefined = 1;
var x; //declared, of type undefined, but...
x === undefined // false, because undefined is 1 and x is of type undefined
As I said before, the safest way to check for an undefined variable(being sure it will work in older environments) is to use typeof:
var undefined = 1;
var x;
typeof x == 'undefined'; //true
Remember also that using equality check(==) with undefined also checks for null(in fact, undefined == null but undefined !== null), so I recommend using strictly equality operator(===), which checks only for undefined.
According to the MDN, undefined became non-writable, starting in JavaScript 1.8.5.
That yields that it was fully "legal" to use it as a variable until then.
But it obviously isn't a good idea.
See a full explanation (I'm not the author) of how 'undefined' is used in JavaScript here http://javascriptweblog.wordpress.com/2010/08/16/understanding-undefined-and-preventing-referenceerrors/
Compared to other languages, JavaScript’s concept of undefined is a
little confusing. In particular, trying to understand ReferenceErrors
(“x is not defined”) and how best to code against them can be
frustrating.
In JavaScript there is Undefined (type), undefined (value) and
undefined (variable).
Undefined (type) is a built-in JavaScript type.
undefined (value) is a primitive and is the sole value of the
Undefined type. Any property that has not been assigned a value,
assumes the undefined value. (ECMA 4.3.9 and 4.3.10). A function
without a return statement, or a function with an empty return
statement returns undefined. The value of an unsupplied function
argument is undefined.
undefined (variable) is a global property whose initial value is
undefined (value), Since its a global property we can also access it
as a variable.
As of ECMA 3, its value can be reassigned :
undefined = "washing machine"; //assign a string to undefined (variable)
typeof undefined //"string"
f = undefined;
typeof f; //"string"
f; //"washing machine"
Needless to say, re-assigning values to the undefined variable is very
bad practice, and in fact its not allowed by ECMA 5 (though amongst
the current set of full browser releases, only Safari enforces this).
Related
The jQuery Core Style Guidelines suggest two different ways to check whether a variable is defined.
Global Variables: typeof variable === "undefined"
Local Variables: variable === undefined
Properties: object.prop === undefined
Why does jQuery use one approach for global variables and another for locals and properties?
For undeclared variables, typeof foo will return the string literal "undefined", whereas the identity check foo === undefined would trigger the error "foo is not defined".
For local variables (which you know are declared somewhere), no such error would occur, hence the identity check.
I'd stick to using typeof foo === "undefined" everywhere. That can never go wrong.
I imagine the reason why jQuery recommends the two different methods is that they define their own undefined variable within the function that jQuery code lives in, so within that function undefined is safe from tampering from outside. I would also imagine that someone somewhere has benchmarked the two different approaches and discovered that foo === undefined is faster and therefore decided it's the way to go. [UPDATE: as noted in the comments, the comparison with undefined is also slightly shorter, which could be a consideration.] However, the gain in practical situations will be utterly insignificant: this check will never, ever be any kind of bottleneck, and what you lose is significant: evaluating a property of a host object for comparison can throw an error whereas a typeof check never will.
For example, the following is used in IE for parsing XML:
var x = new ActiveXObject("Microsoft.XMLDOM");
To check whether it has a loadXML method safely:
typeof x.loadXML === "undefined"; // Returns false
On the other hand:
x.loadXML === undefined; // Throws an error
UPDATE
Another advantage of the typeof check that I forgot to mention was that it also works with undeclared variables, which the foo === undefined check does not, and in fact throws a ReferenceError. Thanks to #LinusKleen for reminding me. For example:
typeof someUndeclaredVariable; // "undefined"
someUndeclaredVariable === undefined; // throws a ReferenceError
Bottom line: always use the typeof check.
Yet another reason for using the typeof-variant: undefined can be redefined.
undefined = "foo";
var variable = "foo";
if (variable === undefined)
console.log("eh, what?!");
The result of typeof variable cannot.
Update: note that this is not the case in ES5 there the global undefined is a non-configurable, non-writable property:
15.1.1 Value Properties of the Global Object
[...]
15.1.1.3 undefined
The value of undefined is undefined (see 8.1). This property has the attributes
{ [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
But it still can be shadowed by a local variable:
(function() {
var undefined = "foo";
var variable = "foo";
if (variable === undefined)
console.log("eh, what?!");
})()
or parameter:
(function(undefined) {
var variable = "foo";
if (variable === undefined)
console.log("eh, what?!");
})("foo")
Who is interested in the performance gain of variable === undefined, may take a look here, but it seems to be a chrome optimization only.
http://jsperf.com/type-of-undefined-vs-undefined/30
http://jsperf.com/type-of-undefined-vs-undefined
Because undefined is not always declared, but jQuery declares undefined in its main function. So they use the safe undefined value internally, but outside, they use the typeof style to be safe.
For local variables, checking with localVar === undefined will work because they must have been defined somewhere within the local scope or they will not be considered local.
For variables which are not local and not defined anywhere, the check someVar === undefined will throw exception: Uncaught ReferenceError: j is not defined
Here is some code which will clarify what I am saying above. Please pay attention to inline comments for further clarity.
function f (x) {
if (x === undefined) console.log('x is undefined [x === undefined].');
else console.log('x is not undefined [x === undefined.]');
if (typeof(x) === 'undefined') console.log('x is undefined [typeof(x) === \'undefined\'].');
else console.log('x is not undefined [typeof(x) === \'undefined\'].');
// This will throw exception because what the hell is j? It is nowhere to be found.
try
{
if (j === undefined) console.log('j is undefined [j === undefined].');
else console.log('j is not undefined [j === undefined].');
}
catch(e){console.log('Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.');}
// However this will not throw exception
if (typeof j === 'undefined') console.log('j is undefined (typeof(x) === \'undefined\'). We can use this check even though j is nowhere to be found in our source code and it will not throw.');
else console.log('j is not undefined [typeof(x) === \'undefined\'].');
};
If we call the above code like this:
f();
The output would be this:
x is undefined [x === undefined].
x is undefined [typeof(x) === 'undefined'].
Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.
j is undefined (typeof(x) === 'undefined'). We can use this check even though j is nowhere to be found in our source code and it will not throw.
If we call the above code like these (with any value actually):
f(null);
f(1);
The output will be:
x is not undefined [x === undefined].
x is not undefined [typeof(x) === 'undefined'].
Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.
j is undefined (typeof(x) === 'undefined'). We can use this check even though j is nowhere to be found in our source code and it will not throw.
When you do the check like this: typeof x === 'undefined', you are essentially asking this: Please check if the variable x exists (has been defined) somewhere in the source code. (more or less). If you know C# or Java, this type of check is never done because if it does not exist, it will not compile.
<== Fiddle Me ==>
Summary:
When at global scope we actually want to return true if the variable is not declared or has the value undefined:
var globalVar1;
// This variable is declared, but not defined and thus has the value undefined
console.log(globalVar1 === undefined);
// This variable is not declared and thus will throw a referenceError
console.log(globalVar2 === undefined);
Because in global scope we are not 100% sure if a variable is declared this might give us a referenceError. When we use the typeof operator on the unknown variable we are not getting this issue when the variable is not declared:
var globalVar1;
console.log(typeof globalVar1 === 'undefined');
console.log(typeof globalVar2 === 'undefined');
This is due to the fact that the typeof operator returns the string undefined when a variable is not declared or currently hold the value undefined which is exactly what we want.
With local variables we don't have this problem because we know beforehand that this variable will exist. We can simply look in the respective function if the variable is present.
With object properties we don't have this problem because when we try to lookup an object property which does not exist we also get the value undefined
var obj = {};
console.log(obj.myProp === undefined);
jQuery probably expects you to be using let and const variables in functions going forward, which in JavaScript's ES6 2015 design do NOT allow you to use any local scope (function) let or const variables until they are declared. Even hoisting by Javascript does not allow you to even type-check them!
If you try and do that, JavaScript generates an error, unlike with var variables which when hoisted creates a declared but uninitialized variable you can type check or check to see if its undefined.
If you declare a let or const variable in a function, but AFTER trying to access it, typeof checks still create a Reference Error in JavaScript! Its very odd behavior, and illogical to me why it was designed that way. But that is why jQuery likely sees no use for typeof function variable use. Example:
function MyError(){
// WOW! This variable DOES NOT EVEN EXIST, but you can still check its type!
if(typeof x === 'undefined')
{
alert(1);// OK!
}
// ERROR!
// WOW! You cannot even check an existing "let" variable's TYPE in a local function!
if(typeof y === 'undefined')//REFERENCE ERROR!!
{
alert(2);
}
// We defined the variable so its hoisted to the top but in a dead zone
let y = 'test';
}
MyError();
// RESULT
// alert 1 fires but a REFERENCE ERROR is generated from the second alert 2 condition.
It is odd above how a non-existing local variable cant be checked using typeof for 'undefined', but a declared let variable in the function cannot! So this is likely why I would not depend on jQuery to define what is best. There are edge cases.
More Weirdness on "undefined" variables in JavaScript
**undefined has two different expressions, and three different uses, as follows:
"typeof" and "undefined" types : Variables that are not declared and do not exist are not assigned anything, but have a "type" of undefined. If you access a variable that does NOT even exist, much less declared or initialized, you will generate a REFERENCE ERROR if you access it, even when testing for the primitive default value of undefined which is assigned to declared variables until assigned a value. So checking the "typeof" prevents this error in this one case as follows:
// In this first test, the variable "myVariable1" does not exist yet so creates
// an error if we try and check if its assigned the default value of undefined!
if (myVariable1 === undefined) alert(true);// REFERENCE ERROR!
// Here we can elegantly catch the "undefined" type
// of the missing variable and stop the REFERENCE ERROR using "typeof".
if (typeof myVariable1 === "undefined") alert(true);// true
// Here we have declared the missing variable and notice its
// still an "undefined" type until initialized with a value.
let myVariable1;
if (typeof myVariable1 === "undefined") alert(true);// true
// Lastly, after we assign a value, the type is no longer
// "undefined" so returns false.
myVariable1 = 'hello';
if (typeof myVariable1 === "undefined") alert(true);// false
All objects and types in JavaScript that are accessed but not declared will default to a type of "undefined". So, the lesson here is try and check for the typeof first, to prevent missing variable errors!
undefined primitive values : All declared variables not yet assigned a value are assigned in JavaScript the primitve of undefined. If you have declared a variable, but not initialized it yet, its assigned this default primitive type of undefined. That is not same as an "undefined" type. The primitive value of undefined is a reserved value but can be altered, but that's not what is asked here. Notice this catches all declared but uninitialized variables only:
let myVariable3;
if (myVariable3 === undefined) alert(true);// true
let myVariable4 = 'hello';
if (myVariable4 === undefined) alert(true);// false
Objects and undefined primitives : Lastly, Object properties do NOT behave like variables in JavaScript. Object properties, when missing do not become undefined types, but are simply assigned the primitive undefined as above for undeclared variables. So they act like #2:
let myObject = {};
if (myObject.myProperty === undefined) alert(true);// true
BEST PRACTICE
Lastly....this is a VERY GOOD REASON to always check for BOTH the "undefined" type and the undefined primitive value on variables in all your JavaScript code. Most will say, you will rarely need both. There may come a day when a missing variable is accessed in a library that does not exist and creates a nasty JavaScript REFERENCE ERROR! So I always do this check, and in this order, to stop all errors in JavaScript:
if (typeof myVariable !== "undefined" && myVariable !== undefined) {
// do something safe with myVariable!
}
typeof a === 'undefined' is faster then a === 'undefined' by about 2 times on node v6.9.1.
Does anyone know why would this happen for below code
if(myVarible !=undefined){ myVarible.doSomething() }
myVariable is A global object that is used only on some pages
I am sure I've done this in a past and it always worked.
I also tried
if(!!s){}
Which I am also sure I've used in the past.
finally got it to work with if(typeof s!=="undefined"){}
but I would like to know why undefined variable is not equal to undefined
and why did it work in the past?
Thanks
From what I understood, the problem is, that on some pages you don't create the global myVarible variable at all.
For such case checks
myVarible !== undefined
and
typeof myVarible !== "undefined"
are not equal. The difference is, that only typeof operator can handle non-existing references to names (e.g. variables). All other language constructs throw ReferenceError when encountering reference that cannot be resolved. typeof returns the string "undefined" for this case.
So, in your case, you should use the typeof operator or check existence of the variable property on global object.
if (window.myVarible) {}
link to ecma-script specification defining typeof behavior
Use if(window.myVarible) instead. If you check for the variable per se, JavaScript will try to execute or check the value of the variable1 which in turn yields this error message.
You can also use if(typeof myVarible !== "undefined") which will only look at the type of the variable but not at its value.
1The way that JavaScript checks for the value of a variable depends on whether that variable was written as an object property like window.myVar or without.
In JavaScript undefined is not a keyword, it is a variable. Sort of special variable. This is known to cause trouble because undefined could be reassigned. I do not really know why would anyone want to do that, but this is possible, and maybe you can experience this by using one of those genius frameworks out there, see the code:
function f() {
var z, undefined = 42
console.log(z, undefined, z == undefined)
} f()
Outputs:
undefined 42 false
Now how does one protect himself from such a confusion? Should one just cross his fingers that undefined is undefined?
Just use void 0, it's simply bulletproof. And it's a keyword too.
You can pass undefined as a function parameter, this will ensure that undefined is undefined in the scope of the function.
Many JavaScript libraries use this technique, for example look at jQuery source code
//jQuery
(function( window, undefined ) {
...
})( window );
Because the function expects two formal parameters, but we only give it one, the other gets the (true) value undefined, and then we can rely on that within the function.
one possibility is to check the type of the variable instead of checking equality to undefied:
if (typeof(VARIABLE) != "undefined")
or read on here: How to check for “undefined” in JavaScript?.
I have seen different code examples with variables declared and set to undefined and null. Such as:
var a; // undefined - unintentional value, object of type 'undefined'
var b = null; // null - deliberate non-value, object of type 'object'
If the code to follow these declarations assigns a value to a or to b, what is the reason for using one type of declaration over another?
The first example doesn't assign anything to the variable, so it implicitly refers to the undefined value (see 10.5 in the spec for the details). It is commonly used when declaring variables for later use. There is no need to explicitly assign anything to them before necessary.
The second example is explicitly assigned null (which is actually of type null, but due to a quirk of the JavaScript specification, claims to have type "object"). It is commonly used to clear a value already stored in an existing variable. It could be seen as more robust to use null when clearing the value since it is possible to overwrite undefined, and in that situation assiging undefined would result in unexpected behaviour.
As an aside, that quirk of null is a good reason to use a more robust form of type checking:
Object.prototype.toString.call(null); // Returns "[object Null]"
I just saw this link which clarified my question.
What reason is there to use null instead of undefined in JavaScript?
Javascript for Web Developers states "When defining a variable that is meant to later hold an object, it is advisable to initialize the variable to null as opposed to anything else. That way, you can explicitly check for the value null to determine if the variable has been filled with an object reference at a later time."
I don't think there's a particular better way of doing things, but I'm inclined to avoid undefined as much as possible. Maybe it's due to a strong OOP background.
When I try to mimic OOP with Javascript, I would generally declare and initialize explicitly my variables to null (as do OOP languages when you declare an instance variable without explicitly initializing it).
If I'm not going to initialize them, why even declare them in the first place? When you debug, if you haven't set a value for a variable you watch, you will see it as undefined whether you declared it or not...
I prefer keeping undefined for specific behaviours:
when you call a method, any argument you don't provide would have an undefined value. Good way of having an optional argument, implementing a specific behaviour if the argument is not defined.
lazy init... in my book undefined means "not initialized: go fetch the value", and null means "initialized but the value was null (eg maybe there was a server error?)"
arrays: myArray[myKey] === null if there is a null value for this key, undefined if a value has never been set for this key.
Be careful though, that myVar == null and myVar == undefined return the same value whether myVar is undefined, null or something else. Use === if you want to know if a variable is undefined.
I would explicitly choose null, to not create an object whose id is later overwritten anyway:
var foo = {}; // empty object, has id etc.
var foo2 = null; // good practice, // filled with an object reference at a later time
var foo3;// undefined, I would avoid it
console.log(typeof foo);
console.log(typeof foo2);
console.log(typeof foo3);
Setting null also ensures good readability to identify the datatype (object),
results in
object
object
undefined
Source (Professional JavaScript for Web Developers 3rd Edition):
When defining a variable that is meant to later hold an object, it is
advisable to initialize the variable to null as opposed to anything
else. That way, you can explicitly check for the value null to
determine if the variable has been filled with an object reference at
a later time, such as in this example:
if (foo2 != null){
//do something with foo2
}
The value undefined is a derivative of null, so ECMA-262 defines them to be superficially equal as follows:
console.log(null == undefined); // prints true
console.log(null === undefined);// prints false
null is an object.. When something is undefined it is nothing.. it is not an object, neither a string, because it hasn't been defined yet.. obviously.. then it is simply a property with no function..
example:
You declare a variable with var but never set it.
var foo;
alert(foo); //undefined.
You attempt to access a property on an object you've never set.
var foo = {};
alert(foo.bar); //undefined
You attempt to access an argument that was never provided.
function myFunction (foo) {
alert(foo); //undefined.
}
I have noticed jQuery and related keynote plugins like jQuery.UI pass undefined as a parameter into anonymous functions used in their module definitions, like so:
(function($, undefined) { ... })(jQuery);
Alternatively, I have noticed other plugins recommended by jQuery and/or others do NOT pass undefined in as a parameter.
This is probably a silly question, but...
Shouldn't it always be available anyway? Why pass it in? Is there some sort of other purpose or trick going on here?
There are two reasons for that:
1) If undefined is a variable in the function scope rather than a global object property, minifiers can reduce it to a single letter thus achieving a better compression rate.
2) Before ES5*, undefined was a property of the global object without write-protection. So it could be overwritten, resulting in strange and unexpected behavior. You could do something like this:
var test = 123;
undefined = 123;
if (test === undefined){
// this will actually be true, since undefined now equals 123
}
By having an function argument undefined (the name actually does not matter) which you don't pass a parameter to, you could make sure you have a variable which really is undefined so you can test "undefinedness" against this variable.
Btw. the safest method to test for undefined is: typeof ( var ) === 'undefined'
(*) With EcmaScript 5, the global properties undefined, NaN and Infinity became readonly. So with its general adoption in all modern browsers - of course with the exception of IE 9 - overwriting those values was not possible anymore.
That is done to make sure that undefined always is undefined. In older versions of the ECMAScript spec (prior to ECMAScript 5), undefined wasn't a reserved word but a regular variable. In older browsers this would be allowed for instance:
undefined = 2; // Assign a different value to undefined
// Now this statement would be true
if (undefined == 2)
So to make sure that undefined is in fact undefined, even if some other "evil" script would have reassigned undefined with another value, you create a parameter that you call undefined, and then when you call the function, you make sure to not pass a value to that parameter - thus you can be sure that the variable undefined will always be undefined within your function.
So in the case of jQuery:
(function($, undefined) { ... })(jQuery);
They pass in jQuery and assign it to the $ variable for convenience, but then they don't pass a second value to the undefined parameter, thus undefined will be undefined.
Modern browsers
In modern browsers, undefined is a non-configurable, non-writable property per the ECMAScript 5 specification.
undefined is not a reserved word in javascript, it is simply a variable. jQuery is ensuring that if some bad developer overwrites the value of undefined in their javascript, then jQuery will ignore it and establish it's own variable, undefined, which is never passed a value (see the self-executing (jQuery) at the end) and is therefore actually undefined.