Reputation: 81
In JavaScript, Why objects cannot be accessed before instantiation unlike function declaration which moves the declaration to the top of its scope and can be called irrespective of its position in the literal code.
Example:
for(var property in myObj)
alert(myObj[property].toString());
var myObj = {
property1: "chocolate",
property2: "cake",
property3: "brownies"
}
Above does nothing not even an error/ log entry in Console. Why?
Upvotes: 0
Views: 90
Reputation: 1972
Function declarations and variable declarations are always moved (“hoisted”) invisibly to the top of their containing scope by the JavaScript interpreter.
Functions are hoisted with the body. So you have complete function that you can call anywhere.
Variable assignments will not be hoisted. Only names declaration. This is not the case with function declarations, where the entire function body will be hoisted as well.
So:
console.log(i); // i is undefined
var i = 1; // value is assigned
console.log(i) // now we get the value
i
is visible anywhere (with undefined
as value) because its been hoisted by the interpreter to the top of scope. But not assigned yet. It assigns when the execution comes to that line of code.
Read more at enter link description here
Upvotes: 0
Reputation: 1075189
Because that's just how the language is designed. Only function declarations and variable declarations (but not initialization) are hoisted. So your code is really:
var myObj = undefined;
var property = undefined;
for(property in myObj)
alert(myObj[property].toString());
myObj = {
property1: "chocolate",
property2: "cake",
property3: "brownies"
};
}
...which fails not because the variable myObj
doesn't exist yet (it does), but because that variable has the value undefined
, and you can't use for-in
on undefined
.
If you think about it, it makes reasonable sense: A function declaration creates a unit of work (a function) based only on its own content, and then is executed later (with any variables it closes over evaluated later, when it's executed), but an object initialization can rely on other things (like variables and such) which would need to be evaluated as of the initialization, not later.
Example:
var answer = 42;
var obj = {
property: answer
};
The declaration of obj
and answer
are hoisted, but it's impossible to hoist the creation of the object we assign to obj
, because it has to use the value of the answer
variable in order to initialize the property property
.
In contrast:
var answer = 42;
foo();
function foo() {
console.log("The answer is " + answer);
}
Both the declaration of answer
and the declaration/creation of the foo
function are hoisted, and that's fine, because although foo
uses answer
, it doesn't use it until later, when it's called.
Upvotes: 4
Reputation: 64943
It depends on how you define a function
.
For example, this function
wouldn't be available too:
func();
// This is a function expression instead of a declaration
var func = function() {};
At the end of the day, you can't use an object literal before instantiating it (see I'm not saying declaring) since it's stored in a reference (i.e. a variable) that won't exist until it's declared!
When declaring functions...
doStuff();
function doStuff() { }
...works because doStuff
is declared once JavaScript run-time has already parsed the code, while the approach of setting a function to some variable happens when the code is actually hit.
An object literal is assigned to some variable and you won't be able to access a variable before it's declared. This is the simplest way of explaining your concern.
Upvotes: -1
Reputation: 333
Firstly, hoisting makes this code work as if it was:
var myObj = undefined;
for(var property in myObj)
alert(myObj[property].toString());
myObj = {
property1: "chocolate",
property2: "cake",
property3: "brownies"
}
Therefore, myObj is undefined when for-in loop executes. The fact that myObj has no properties (its undefined at that point) makes for-in loop not execute any single time (that is why you don't receive any error).
Upvotes: 0
Reputation: 3062
That is because functions declare only definition, and this definition could be visible in all your code. Of course in proper scope.
function test() {
}
However by defining variables, you create physical object. It is created just in time of executing this line of code, so it is not visible earlier.
var testData = {};
var testFunction = function() {
}
Upvotes: 0