<html>
  <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
      <script>
            var name = "The Window";   //相当于 window.name = "The Window";
            
            /****************字面量创建对象**************/
            var object1 = {   
              name : "My Object1",   
              getNameFunc : function(){   
                return function(){   
                  return this.name;   
                 };   
              }   
            };   
            
            function showThis1(){
               alert(object1.getNameFunc()());  //The Window
            }
            var object2 = {   
              name : "My Object2", 
                //方法
              getNameFunc : function(){ 
                    //方法内的this指针指向调用方法的对象,所以that引用了正确的对象object2
                    var that = this;
                    //函数
                return function(){   
                  return that.name;   
                 };   
              }   
            };  
            function showThis2(){
               alert(object2.getNameFunc()());  //My Object2
            }
            /***************字面量创建对象**************/
            /***************工厂模式创建对象,利用函数返回一个对象***********/
            /*工厂模式创建对象,可利用内部函数形成闭包,创建较为复杂的对象*/
            var object3 = (function(){
                function getName(){
                   return this.name;
                }
                return {
                    name : "My Object3",
                    //这种写法与Object1是同一种情况
                    getNameFunc : function(){
                       return getName(); 
                  }
                }
            })();
            function showThis3(){
               alert(object3.getNameFunc());  //Window
            }
            
            var object4 = (function(){
                return {
                    name : "My Object4",
                    getNameFunc : function(){
                       return this.name; 
                  }
                }
            })();
            function showThis4(){
               alert(object4.getNameFunc());  //My Object4
            }            
            var object5 = (function(){
                
                //函数内的this 默认指向window,这里的that依然指向window而不是object5
                var that = this;
                function getName(){
                   return that.name;
                }
                return {
                    name : "My Object5",
                    getNameFunc : function(){
                        return getName();
                  }
                }
            })();
            function showThis5(){
               alert(object5.getNameFunc());  //Window
            }
            /***************工厂模式创建对象**************/
            
            /***************构造方法创建对象**************/
            /*构造方法比较特殊,其this指针指向待返回的对象,
              而不是window,注意构造方法的函数首字母一定要大写*/
            function Object6(){
                this.name = "My Object6";
                this.getNameFunc = function(){
                      return this.name;
                }
            }
            var object6 = new Object6();
            function showThis6(){
               alert(object6.getNameFunc());  //My Object6
            }
            function Object7(){
                //但是构造函数内部定义的函数this指针仍然指向window,依然需要注意
                function getName(){
                   return this.name;
                }
                this.name = "My Object7";
                this.getNameFunc = function(){
                      return getName();
                }
            }
            var object7 = new Object7();
            function showThis7(){
               alert(object7.getNameFunc());  //Window
            }
            /***************构造方法创建对象**************/
   
            /*使用上述方式创建对象均有一个缺陷,
              就是每一个object实例均有不同的getNameFunc,而不是共享为一个,
              浪费了内存空间,使用原型模式创建对象可以解决这个问题*/
            /*******原型模式创建对象*********/
            function Object8(){
            }
            
            //相当于Java中被共享的属性 public static String name;
            Object8.prototype.name = "My Object8";
            //相当于Java类中的函数 public String getNameFunc(){...};
            Object8.prototype.getNameFunc = function (){
               return this.name;
            }
            var object8 = new Object8();
            
            /*这样,每一个利用构造函数Object8创建出来的对象,均共享了getNameFunc节约了内存空间。
              但是由于原型对象是被所有子对象所共享的,所以子对象同时共享了name属性,
              若某一个对象修改了name属性的值,其它对象的name会同时改变,这显然是不希望看到的*/
            var object8_bro = new Object8();
            function showThis8(){
               alert(' object8: ' + object8.getNameFunc() 
                     + '\n object8兄弟: ' + object8_bro.getNameFunc());
               alert('object8兄弟改名了!');
               object8_bro.name = 'Object8魔改';
               alert(' object8: ' + object8.getNameFunc() 
                     + '\n object8兄弟: ' + object8_bro.getNameFunc() 
                     + '\n WTF,两兄弟同时改名了!');
            }
            /*******原型模式创建对象*********/
            
            /********组合使用原型模式和构造函数创建对象**************/
            /*为了解决这个问题,可组合使用原型模式和构造函数创建对象,
              即公共方法写在原型对象中 ,私有变量写在构造方法中 。
              这也是许多jQuery插件之中经常使用的创建对象的方式*/
            function Object9(){
                 this.name = "Object9"
            }
            
            Object9.prototype.getNameFunc = function(){
                 return this.name;
            }
            var object9 = new Object9();
            var object9_bro = new Object9();
            function showThis9(){
               alert(' object9: ' + object9.getNameFunc()
                      + '\n object9兄弟: ' + object9_bro.getNameFunc());
               alert('object9兄弟改名了!');
               object9_bro.name = 'Object9魔改';
               alert(' object9: ' + object9.getNameFunc()
                     + '\n object9兄弟: ' + object9_bro.getNameFunc() + '\n该是谁还是谁!');
            }
            /********组合使用原型模式和构造函数创建对象**************/
            //稍稍改动下,像不像一个jQuery插件,像不像一个java的类呢
            var jQuery = {};
                   
            ;(function($){
                 
                 //构造函数
                 function Object10(){
                     //私有变量
                     this.name = "Object10"
                 }
                 //公有函数 
                 Object10.prototype.getNameFunc = function(){
                     return _getName(this);
                 }
                 $.createObject10 = function(){
                     return new Object10();
                 }
                    
                 //闭包私有函数
                 function _getName(that){
                     //注意this指针!!
                     return that.name.toUpperCase();
                 }
                 
            })(jQuery);
            var object10 = jQuery.createObject10();
            function showThis10(){
                 alert(object10.getNameFunc());  
            }
      </script>
  </head>
  <body>
        <button onclick = "showThis1()"> this1 </button>
        <button onclick = "showThis2()"> this2 </button>
        <button onclick = "showThis3()"> this3 </button>
        <button onclick = "showThis4()"> this4 </button>
        <button onclick = "showThis5()"> this5 </button>
        <button onclick = "showThis6()"> this6 </button>
        <button onclick = "showThis7()"> this7 </button>
        <button onclick = "showThis8()"> this8 </button>
        <button onclick = "showThis9()"> this9 </button>
        <button onclick = "showThis10()"> this10 </button>
  </body>
<html>