javascript面向对象编程

来源:互联网 发布:第一学历 知乎 编辑:程序博客网 时间:2024/03/29 00:53

   

一、javascript支持两种方式声明类:

      1. 使用函数声明:

         eg:  function Test(){
                     this.prop = 'test';
                     var bar = "bar";
                     this.fa = function(){
                            alert('fa'); 
                     }
                  }
                 Test.staticProp = "static prop";
                 Test.staticMethod= function (){
                          …
                  }

          (1)示例中this.prop为类的公开的属性,而bar是一个私有属性,私有属性只能在当前函数中使用。

          (2)staticProp和staticMethod为该类的静态属性及静态方法,静态属性及方法只能通过类引用。

       2. 使用对象的prototype的方式声明类   
             eg:  function Test(){ }

                       Test.prototype = {

                            prop:’test’,

                            fa: function(){ alert(‘fa’); }

                        };//大括号声明了一个匿名的对象

                        var test = new Test();

                       alert(test.prop);//得到test字符串

                     }

二、对象实例化

        JavaScript提供了new操作符来获得对象实例。

         如果没有实例化的类输出会是怎样呢?

         eg:   function Animal(name){   //创建javascript类
                    this.name = name;
                    this.age = 0;
                }

               var a1 = Animal;

               alert(a1);    //输出整个函数的字符串

                var a2 = Animal();

                alert(a2); //输出defined,因为没有return值

                var a3 = new Animal();

                alert(a3);   //输出是object,实例化对象方法1

                var a4 = new Animal;

                alert(a4);  //输出是object,实例化对象方法2

        eg2:  var obj = new Object();

               obj.name = "zhansan";

 三、 获取或设置对象中的方法或属性          

             javascript提供了3种方式来访问和设置对象的属性和方法:

             (1)  点操作符

                    对象名.属性名;
                    对象名.方法名;

             eg:  var obj = new Object();
                    obj.Now= new Date();
                    alert(obj.Now);    

             提醒:不必预先声明属性Now —如果 obj没有该名称的属性,该属性将被直接添加到 obj    

             (2)  方括号引用
                    对象名["属性名"];
                    对象名["方法名"];

             注意:[ ]里面的不一定是字符串,也可以是变量。

             eg:  var obj=new Object();
                    obj["Now"]=new Date();
                    alert(obj.Now);
             (3)  大括号应用(设置属性或方法)

                   { 属性名:属性值,方法名:方法 }

              eg:  var obj={Now: new Date()};  //通过{}来进行属性赋值
                     alert(obj.Now);   //效果同上

四、重载模拟  --  函数的参数可变性(arguments)

           javascript不支持重载,但支持方法参数的可变。 通过arguments可以获取传进的参数值。

           arguments主要有2个属性:

  •   length  --  获得参数的个数
  •   callee  --  获得参数所对应的函数

           eg1:  <script language="javascript">
                     function sum()
                     {
                           var s= 0;
                           for(var i=0; i<arguments.length; i++)
                                  s+=  arguments[i];
                                  return s;
                      }
                      sum(1,2);
                     sum(3,4,5);
                   </script>

           eg2:  var factorial = function(n){
                          if(n <= 0)   return 1;
                          return n * argments.callee(n – 1);
                     }

五、call和apply

          call, apply都属于Function.prototype的一个方法,所以每个Function对象实例,也就是每个方法都有call, apply属性

          用法:调用一个对象的一个方法,以另一个对象替换当前对象。可以用来动态改变函数执行的作用域。

           eg:  var b1={v:"this is b1"};
                 var b2={v:"this is b2"};
                 function b(d){
                       alert(this.v + d);
                  }
                 b("a");      //输出:defined 
                 window.b("a");   //输出: defined,同上
                 b.call(b1+"a");    //输出:this is b1
                 b.apply(b2+["a"]);   //输出:this is b2

           applycall的区别在于调用时参数的形式不同。如上,apply参数以[ ]传递

六、prototype

           类名.prototype.方法名 = function(){
                    ...

            }

            作用:

               (1)  给已有类添加新方法(扩展方法)

               (2)  重新定义类的方法

            注意:

  •    prototype只能访问类的公共成员和方法
  •    当我们访问对象的一个成员时,先在对象内部找,如果找不到,则到对象所在类的prototype对象中找
  •   通常我们声明类的方法用prototype来声明,可以减少new创建对象时不必要的方法占用内存空间。

             eg:   Number.prototype.add = function(b){
                             return this+b;
                     }
                     Array.prototype.indexOf = function(v){
                           for(var j=0; j<this.length;j++)
                           {
                                  if(this[j] == v)
                                      return j;
                            }
                            return -1;
                      }

七、继承

            javascript对象继承通常有下面的5种方式:

  •   对象冒充
  •   call()方式
  •   apply()方式
  •   原型链
  •   混合方式

           1.  对象冒充

           eg:  function classA(name) {
                      this.name=name;
                      this.showName=function(){alert(this.name);}
                   }
                  functionclassB(name) {
                        this.newMethod = classA;
                        this.newMethod(name);
                  }
                  obj = new classA("hero");
                  objB = new classB("dby");
                  obj.showName();      //   print hero
                  objB.showName();    // print dby  说明classB 继承了classA的方法.
                  对象冒充可以实现多重继承 例如
                 function classz(){
                     this.newMethod = classX;
                     this.newMethod();
                    delete this.newMethod;  
                  }

            2.  call方法

             eg:   function sayName(perfix) {
                          alert(perfix+this.name);
                      }
                     obj= new Object();
                     obj.name="hero";
                     sayName.call(obj,"hello," );
                     function classA(name) {
                          this.name=name;
                          this.showName=function(){alert(this.name);};
                     }
                    function classB(name) {
                         classA.call(this,name);     //classA类中的this都改成classB对象的this
                    }
                    objB = new classB("bing");
                    objB.showName();    //说明classB继承classA的showName方法

              3.  apply方法

               eg:  function sayName(perfix)  {
                           alert(perfix+this.name);
                       }
                      obj= new Object();
                      obj.name="hero";
                      sayName.apply(obj,new Array("hello") );

              4.  原型链

                   prototype对象的任何属性和方法都会被传递给对应类的所有实例,原型链就是用这种方式来显现继承.

               eg:  function classA () { }
                      classA.prototype.name="hero";
                      classA.prototype.showName=function() { alert(this.name) }
                      function classB() { }
                      classB.prototype=new classA();
                      objb = new classB()
                      objb.showName();  //print hero  说明b继承了a的方法

                缺点:不能传递参数,不支持多继承

                注意:子类的所有属性和方法,必须出现在prototype属性被赋值后,因为在它之前赋的值会被删除.因为对象的prototype属性被替换成了新对象,添加了新方法的原始对象将被销毁.

               5. 混和方式

                    用冒充方式 定义构造函数属性,用原型法定义对象方法.
               eg:  function classA(name) {
                           this.name=name;
                      }
                      classA.prototype.showName=function(){alert(this.name)}
                      function classB(name) {
                            classA.call(this,name);
                      }
                      classB.prototype = new classA();
                      classB.prototype.showName1=function() { alert(this.name+"*****"); };
                      obj = new classB("hero");
                      obj.showName();
                      obj.showName1();

          

 

  

附录: 

(1)获取对象myObject里面属性的个数:

Object.getOwnPropertyNames(myObject).length


原创粉丝点击