I'm doing some experimenting with this malicious JavaScript line: var undefined = true;
Every uninitialized variable in JavaScript has the value of undefined which is just a variable that holds the special value of 'undefined', so the following should execute the alert:
var undefined = true,
x;
if (x) {
alert('ok');
}
But it doesn't, and my question is why?
On further experimentation, I tried the following:
var undefined = true,
x = undefined;
if (x) {
alert('ok');
}
This time, the alert is executed.
So my question is...since in the first snippet x holds undefined (because it is not initialized), why didn't the alert execute? The strange thing is that when explicitly stating that x is undefined (x = undefined), the alert executed...
There is a difference between a variable named undefined and the value called undefined.
var undefined = true,
x;
In this example, the variable undefined is set to the value true, and x to the value (not the variable!) undefined.
var undefined = true,
x = undefined;
In this example, the variable undefined is set to the value true as well, and x is set to the value contained in the variable undefined (which is true).
So, while you can declare a variable named undefined, you cannot change the fact that non-initialized variables are set to the value undefined.
Just declaring a variable called "undefined" does not mean that you're overriding the built-in concept of what the native "undefined" value is.
Imagine if Java would let you use "null" as an identifier. Well, I guess Java doesn't have the same coercion as Javascript. Anyway the Javascript statement
if (x) alert("foo");
involves an implicit coercion of the value of "x" to boolean. The value isn't defined, so its coercion to "boolean" results in false.
Uninitialized variables get the special value undefined. When you assign a variable to another variable you're giving it a string that references a variable you've defined within the current scope. In this case you've defined a variable named undefined so the JavaScript engine will look first through the variables, see that you've named one undefined and then assign it that variable.
Related
Why an assigned variable in JS is undefined when inspected in dev tools?
for example,
var x = 5;
results in undefined in devtools.
console does not evaluate the value of x, but it evaluates the expression itself,expressions are always undefined in javascript.
Example 1 =>
var x = 55; // undefined
It declares the variable x and assigns it the value of undefined. That is the value we get back as feedback on the console.
Then, it finally assigns the value of 55 to x. At this time the console has already returned a value so we don't get to see the value 55 as feedback when we declare and assign a variable at once.
On the other hand, if we reassign variable x to a different value at a later time, we will get the new value as feedback instead of undefined:
Example 2 =>
x = 57; //57
We are declaring a variable but of which type it does not define (like string, int, or boolean) that's why it displays undefined as a first statement. after it assigns a value to a variable and decides the type of variable in Javascript.
like var a=10; // undefined as first time when var is created.
typeof(a) // "number" in second statement
-- IN addition for the function in Javascript ---------------
(function (){return("OK")})()
(function (){})()
Undefined is about the return value of a function call.
You only see something useful when a function returns value.
If nothing is returned then you see undefined.
In Javascript, I can do
> var foo;
< undefined
> foo;
< undefined
This suggests that in Javascript, declared uninitialized variables are always undefined. But are they? Or could they, like in C, take on a random garbage value?
MDN's var docs weren't of help.
They won't take a random garbage value, if no value is assigned, it will stay "undefined".
That gives the possibility to check if an object as yet been assigned :
From MDN :
function test(t) {
if (t === undefined) {
return 'Undefined value!';
}
return t;
}
var x;
console.log(test(x));
// expected output: "Undefined value!
A variable that has not been assigned a value is of type undefined. A
method or statement also returns undefined if the variable that is
being evaluated does not have an assigned value. A function returns
undefined if a value was not returned.
In javascript any property that has not been assigned a value it is assigned as undefined. There are two things you need to seperate to understand it, there are two Undefined "things" from ECMA-262 Standard:
4.3.9 undefined value
4.3.10 Undefined type
Undefined type => type whose sole value is the undefined value
undefined value=> primitive value used when a variable has not been assigned a value
So in your case the variable is initialized and it has been assigned the undefined value.
Also a premitive value in javascript is defined as:
4.3.2 primitive value
member of one of the types Undefined, Null, Boolean,
Number, or String as defined in Clause 8
NOTE: A primitive value is a datum that is represented directly at the
lowest level of the language implementation.
Playing with javascript closures I end up with this question I cannot reach to explain.
(function() {
console.log("Inside closure"); //does not work
}(foo));
It does not work because foo is undefined. referenceError
But if prior I set var foo = undefined; it works (tested on Chrome and ff).
It is not the same to be undefined that to be set to undefined?
example in jsfiddle
In javaScript, 'undefined' is one of the primitive data types. It represents the type of an object.
var a = undefined;
var b;
console.log((typeof(a)));
console.log((typeOf(b)));
The output will be undefined for both the cases.
If you don't declare a variable at all and try to access it, the error thrown will be the following. I tried to access c which is not declared at all.
Uncaught ReferenceError: c is not defined(…)
Having a variable whose value is undefined is not the same as having no variable with that name.
In ECMAScript, identifiers are resolved according to Identifier Resolution, which returns a reference given by GetIdentifierReference.
In case the variable doesn't exist, the base value of that reference will be undefined, otherwise it will be an environment record.
When GetValue gets the value of that reference, it will check IsUnresolvableReference. If the base value is undefined, it will return false, and GetValue will throw a ReferenceError exception.
If the variable exists (even if its value is undefined), GetValue will return its value.
If you are not sure whether some variable exists, you can use the typeof operator, which returns "undefined" for unresolvable references instead of throwing.
If the question is:
But what if somebody uses the the common jQuery wrapper and has the jQuery script not working yet?
Then you will still get a reference error if the jQuery identifier is not in the global scope because it is trying to find the reference to jQuery but it will not exist.
the undefined keyword is passed in the closure so that if undefined is assigned a value, it will not mess with your code. For example:
var undefined = 123
if(undefined){
console.log("pass")
}
this code will pass. If you Pass through undefined but leave out the parameter when you invoke it, undefined will have not a value assigned to it. It wont be looking for a reference as you haven't assigned the parameter For example :
(function(undefined){
// undefined will be undefined.
}())
I've done a quick example here for you : https://jsfiddle.net/gn7h3641/
TLDR : if your asking JavaScript for the value of a variable that doesn't exist(not been defined with var), it will explode because it has not got a reference to find the value yet which is different to checking if something is undefined in a 'if(test === undefined)'
On this page, it shows some example code, containing the following line:
var Subject = ( function( window, undefined ) {
What is the undefined as a function parameter?
This is used to prevent from overriding the value of undefined in non-strict mode.
In non-strict mode, the value of undefined can be override by assigning other value to it.
undefined = true; // Or any other value
So, using the value of undefined will not work as expected.
In strict-mode, undefined is read-only and assigning value to it will throw error.
In the code, the value to the last parameter is not passed, so it'll be implicitly passed as undefined.
var Subject = ( function( window, undefined ) {
}(window)); // <-- No parameter is passed for the last value
That is done to make sure that undefined always is undefined. In JavaScript, since undefined isn't a reserved word but a regular variable, this would be allowed for instance:
undefined = 2; // Assign a different value to undefined
if (undefined == 2) // Now this statement would be true
So in your case
var Subject = ( function( window, undefined ) {
They pass in window and use it , but then they don't pass a second value to the undefined parameter, thus undefined will be undefined.
Because you used to be able to redefine the value of undefined, but not anymore. Undefined is a special type that has several use cases. If it was redefined to true, code like this would break:
if(my_var === undefined) {
dont_load_missiles());
} else {
load_missiles();
}
I recently asked a similar question ( SO link ) and the community suggested this article.
Following statements in the selected answer ( link ) theoretically answers the question;
This is used to prevent from overriding the value of undefined in non-strict mode.
In non-strict mode, the value of undefined can be override by assigning other value to it.
I believe a practical example might be helpful
var undefined = 7;
function printUndefined(undefined) {
document.getElementById("output").innerHTML += undefined + "<br/>";
}
printUndefined(); // Output is undefined
printUndefined(undefined); // Output is 7
printUndefined(10); // Output is 10
JSfiddle
Therefore the only guarantee is that the method caller is in control of the context.
Everything I've ever read indicates that in Javascript, the boolean value of an undefined variable is False. I've used code like this hundreds of times:
if (!elem) {
...
}
with the intent that if "elem" is undefined, the code in the block will execute. It usually works, but on occasion the browser will throw an error complaining about the undefined reference. This seems so basic, but I can't find the answer.
Is it that there's a difference between a variable that has not been defined and one that has been defined but which has a value of undefined? That seems completely unintuitive.
What is a ReferenceError?
As defined by ECMAScript 5, a ReferenceError indicates that an invalid reference has been detected. That doesn't say much by itself, so let's dig a little deeper.
Leaving aside strict mode, a ReferenceError occurs when the scripting engine is instructed to get the value of a reference that it cannot resolve the base value for:
A Reference is a resolved name binding. A Reference consists of three
components, the base value, the referenced name and the Boolean valued
strict reference flag. The base value is either undefined, an Object,
a Boolean, a String, a Number, or an environment record (10.2.1). A
base value of undefined indicates that the reference could not be
resolved to a binding. The referenced name is a String.
When we are referencing a property, the base value is the object whose property we are referencing. When we are referencing a variable, the base value is unique for each execution context and it's called an environment record. When we reference something that is neither a property of the base object value nor a variable of the base environment record value, a ReferenceError occurs.
Consider what happens when you type foo in the console when no such variable exists: you get a ReferenceError because the base value is not resolvable. However, if you do var foo; foo.bar then you get a TypeError instead of a ReferenceError -- a subtle perhaps but very significant difference. This is because the base value was successfully resolved; however, it was of type undefined, and undefined does not have a property bar.
Guarding against ReferenceError
From the above it follows that to catch a ReferenceError before it occurs you have to make sure that the base value is resolvable. So if you want to check if foo is resolvable, do
if(this.foo) //...
In the global context, this equals the window object so doing if (window.foo) is equivalent. In other execution contexts it does not make as much sense to use such a check because by definition it's an execution context your own code has created -- so you should be aware of which variables exist and which do not.
Checking for undefined works for variables that have no value associated but if the variable itself hasn't been declared you can run into these reference issues.
if (typeof elem === "undefined")
This is a far better check as doesn't run the risk of the reference issue as typeof isn't a method but a keyword within JavaScript.
Is it that there's a difference between a variable that has not been defined and one that has been defined but which has a value of undefined?
Yes. A undeclared variable will throw a ReferenceError when used in an expression, which is what you're seeing.
if (x) { // error, x is undeclared
}
Compared to;
var y; // alert(y === undefined); // true
if (y) { // false, but no error
}
That seems completely unintuitive.
Meh... what I find unintuitive:
if (y) // error, y is undeclared
var x = {};
if (x.someUndeclaredAttribute) // no error... someUndeclaredAttribute is implictly undefined.
Here's an example of Jon's explanation regarding environment records:
var bar = function bar() {
if (!b) { // will throw a reference error.
}
},
foo = function foo() {
var a = false;
if (a) {
var b = true;
}
if (!b) { // will not throw a reference error.
}
};
In strict mode, it is an error:
function a() {
"use strict";
if (!banana) alert("no banana"); // throws error
}
It's always really been better to make an explicit test for globals:
if (!window['banana']) alert("no banana");
It doesn't make sense to perform such a test for non-global variables. (That is, testing to see whether the variable is defined that way; it's fine to test to see whether a defined variable has a truthy value.)
edit I'll soften that to say that it rarely makes sense to thusly test for the existence of non-globals.
When a variable is declared and not initialized or it's used with declaration, its value is "undefined". The browser complains exactly when this undefined variable is referenced. Here "reference" means some piece of javascript code is trying to visit an attribute or method of it. For example, if "elem" is undefined, this will throw an exception:
elem.id = "BadElem";
or you use try/catch:
try { x } catch(err){}
This way you're not doing anything in case of an error but at least your script won't jump off the cliff...
undefined = variable exists but has no value in it
ReferenceError = variable does not exist