I was looking at code like this

 
var foo = (function () {
    var obj = {
        a: 1,
        hello: "HelloWorld",
        bar: function () {
            console.log ("accessing the containing object " + obj.a + obj.hello);
        }
    };
    return obj;
})() ;
 
 

And suddenly I feel confusing about the function defined in obj var literal definition. Its accessing the obj var's properties inside the function which is also a part of the objection definition(at least it looks like so).

This is unusual for most people who get used to the forward declaration in most imperative languages, especially the C language.

First thing to make clear is the function is not part of the object literal definition, the following is equivalent

 
var foo = (function () {
    var obj = {
        a: 1,
        hello: "HelloWorld",
        bar: bar
    };
 
    function bar () {
        console.log ("accessing the containing object " + obj.a + obj.hello);
    }
    return obj;
})() ;
 

Obviously, in Javascript you are able to reference a function before its declaration. The reason is that Javascript support the so called function hoisting. All function declarations are hoisted to top level like some kind of preprocessing. A question one may ask is when the function is hoisted, did the variable for example the obj here is evaluated? Because in function bar, the obj is referenced, then the variable obj musted already been evaluated, and it must happens before the hoisting, but to evaluate the variable, we must also evaluate the function, since obj referenced the function. This is a circular dependency.

Another example

 
function func1 () {
  console.log("calling func1")
  func2();
}
 
function func2() {
  console.log("calling func2")
  func1();
}
 

This is just a mutual recursion.

When we say hoist a variable or a function, we should be clear what exactly we are hoisting. A variable or a function should be thought of as two parts thing: declaration and definition. Is the declaration part is hoisted, not the definition.

After hoisting the previous example equivalent to below.

 
var foo = (function () {
    var obj; // variable hoisting
 
    // function hoisting
    function bar  () {
        console.log ("accessing the containing object " + obj.a + obj.hello);
    }
 
    obj = {
        a: 1,
        hello: "HelloWorld",
        bar: bar
    };
 
 
    return obj;
})() ;
 

The conclusion is that only the name is hoisted, not the definition. In previous example, both obj and bar are hoisted, but not their definition, so the circular reference does not exist.