the first line fun (). Fun () 
 first executes fun () because there is console.log ('foo') in it, so this is the first to print 
, then execute the following return to return an object, and then call the fun in the object, and then fun () inside because the closure, the outermost fun will not be destroyed, it will execute the outermost fun all have the second print 
 the second line fun (). Fun (). Fun () will also output two foo before and above, but fun (). Fun () has nothing to return, so it is undefined 
.
  fun ()  returns an object that is return and contains a member named fun, so fun (). Fun () executes 
 function () {fun ()}  and returns undefined, so 
 fun (). Fun (). Fun ()  returns  
function fun(){
    console.log('foo');
    return {
      fun: function(){
        return fun();
      }
    };
}
If you change it to this way, you can loop indefinitely. You didn't reverse the return value .
function fun(){
        console.log('foo');
        return {
            fun: function(){
                fun();
                return this;
            }
        };
    }
    fun().fun(); // 'foo','foo'
    fun().fun().fun();
The undefined returned by 
 fun (). Fun () cannot continue. Go down 
 when executed for the first time, the return value is 
fun: function(){
    fun();
}
 fun (). Fun () is the fun property that returns the value, and then executes, which is equivalent to 
(function(){
    fun();
})();
 take a look at the function executed this time, it doesn't write return. There is no return value, and the return value is undefined. The return value of fun (). Fun () has no fun attribute, fun (). Fun (). Fun of course reported an error. 
 fun (). Fun (). Fun () 
 look separately: the first step of: fun (). Fun () execution is 
 fun: function(){
                fun();
                return this;
            }
 is him, but there is no return after his execution. If the function does not have return, it returns undefined, 
 so undefined does not have the attribute of fun 
.