首先看一个页面常用的js代码骨架

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>js面对对象编程</title>
</head>
<body>
<script type="text/javascript" src="../js/lib/jquery-1.11.0.js"></script>
<script type="text/javascript">
;(function($){
    var Obj = function(){//定义一个类
        console.log(this);//==>Obj
        this.init();
    }
    
    Obj.prototype = {//对象原型
        constructor:Obj,//构造函数
        ObjName:"我是一个对象",
        saySomething:function(){
            console.log(this.ObjName);
        },
        init:function(){
            this.saySomething();
        },
        print:function(str){
              console.log("Obj里的输出:"+str);
      console.log(this);
}
    };
    
    var Obj2 = function(){}
Obj2.prototype = new Obj();//类的继承
console.log("Obj2.ObjName:"+new Obj2().ObjName); 
        //==>Obj2.ObjName:我是一个对象
Obj2.prototype.ObjName = "我继承了Obj.ObjName并且重写了它";
console.log("Obj2.ObjName:"+new Obj2().ObjName); 
         //==>Obj2.ObjName:我继承了Obj.ObjName并且重写了它
Obj2.prototype.print = function print(str){
     console.log("Obj里的输出:"+str);
     console.log(this);
};
    
    $(document).ready(function($) {
        var obj = new Obj();//实例化类 ==>输出:我是一个对象
        var obj2 = new Obj2();//实例化类 ==>输出:我是一个对象
console.log("Obj2.ObjName:"+obj2.ObjName); 
      //==>Obj2.ObjName:我继承了Obj.ObjName并且重写了它
        console.log(this);//==>#document
        obj2.print('试试1');//==>Obj2里的输出试试1,Obj2 {}
obj.print('试试2');//==>Obj里的输出:试试2,Obj {}
obj.print.call(obj2,'试试3');//==>Obj里的输出:试试3,Obj2 {}
obj.print.call(window,'试试4');//==>Obj里的输出:试试4,Window
obj2.print.call(obj,'试试5');//Obj2里的输出试试5,Obj {}

    });
    
    console.log(this);//==>Window
})(jQuery);
console.log(this);//==>Window
</script>
</body>
</html>



代码分析:

一、立即执行函数表达式IIFE

        IIFE immediately-invoked function expression 

    写法一(function($){...})(jQuery);

    写法二(function($){...}(jQuery));

    其作用相当于

                   var a = function($){...};

                   a(jQuery);

                   让编写的代码能立即执行。

    

二、function(){}

      在javascript中定义类函数都是funciton。


三、Obj.prototype类原型

      可以像上面那样写在一起,这叫完全重写;

     也可以分开写,叫做部分重写,写法如下:

      Obj.prototype.a = "我是字符串";

      Obj.prototype.b = {

                                        name:"我是对象"

                                       };

      Obj.prototype.c = ['我是','数组'];

      Obj.prototype.d= function(){

                                       return "";

                                       我是函数

                                         };


四、$(document).ready(function(){...});

       因为html文档是顺序执行的所以如果代码是写在所有文档元素之后这个$(document).ready()可以省略 



五、call

    函数名.call(调用者, 参数列表); //调用者不能省略,定义了这个函数的作用哉

  


六、js代码前的分号;或加号(+)是为了避免前一个js文档如果没有用分号结尾造成的文档错误。


七、constructor构造函数

    构造函数:是一种特殊的方法,主要用来在创建对象时初始化对象,即为对象成员变量赋初始值。总与new运算符一起使用在创建对象的语句中,特别的一个类可以有多个构造函数,可根据其参数个数的不同或参数类型的不同来区分它们,即构造函数的重载。

    在JavaScript中,对象的constructor属性用于返回创建该对象的函数引用。

    每个具有原型的对象都会自动获得constructor属性。除了arguments、Enumerator、Error、Global、Math、RegExp、Regular Rxpression等一些特殊对象之外,其他所有的JavaScript内置对象都具备constructor属性。例如:Array、Boolean、Date、Function、Number、Object、String等。所有主流浏览器均支持该属性。

    当prototype完全重写的时候(就是Obj.prototype = {}的形式),这时prototype的构造器是Object,宿主构造器不直接具备prototype的属性,也正因如此,在prototype声明之前已经创建好的对象,不能使用prototype属性——完全重写将原来的实例和prototype切断了。

    prototype的部分重写,是在原来的基础上新增了属性或者方法,而完全重写则是推翻原有的,重新开始,那么,如果即想把所有新增方法都写在一起,又要保留原有的属性的时候,就需要用到“constructor:类名称”这句话把构造器指回来。