您的位置:首页 > Web前端 > JavaScript

javascript面向对象编程

2012-04-29 11:00 204 查看
   

一、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

           apply与call的区别在于调用时参数的形式不同。如上,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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息