You're confusing a couple of different things here.
Your first statement is a function expression, not a function declaration:
(function foo() {
var a = 3;
console.log(a);
});
This happens to be a named function expression ("foo"), but it does not introduce a variable foo
in this scope. If you wanted to introduce foo
so that it can be called again, you need either a function declaration...
function foo() {
var a = 3;
console.log(a);
}
foo();
or, you need to assign the function expression to a variable:
var foo = function () {
var a = 3;
console.log(a);
}
foo();
Your next bit of code, the object declaration, effectively does this by assigning the function expression to a variable, obj.a
:
var obj = {
a: (function foo() {
var a = 2;
console.log(a);
})
};
The error in your thinking here is due to confusion around foo
. In both cases, foo
is the name of the function, but it's not actually relevant to invoking the function. You should drop the foo
because it's only confusing things.
In essence, your first snippet is equivalent to:
(function () { alert('x'); });
This line of code defines an anonymous function, but does nothing with it. The function exists briefly, is never invoked, and then is lost, because it is not assigned to anything.
Your second snippet is equivalent to:
var x = function () { alert('y') };
This code defines a variable, x
, and assigns a function to it. The function can then be invoked with x()
, and the function remains available as long as x
is in scope.
Your original question is:
How can an object access function expression?
Which doesn't really make sense. The object can't "access the function expression", it just contains a property to which a function has been assigned, while the snippet outside the object did not retain the function in a way that would allow you to invoke it.