Javascript面向对象编程(OOP)

1.属性、方法和原型对象

    function People(name, sex, deposit) {
      this.name = name;
      this.sex = sex;
      var deposit = deposit;                          //私有属性deposit(存款)
      this.consume = function (money) {               //公有方法consume(消费)
        if (deposit >= money) {
          deposit -= money;
        } else {
          throw new Error("没有足够存款");
        }
      }

      var that = this;                                //保存当前对象到变量that中供私有方法使用
      var digest = function (food) {                  //私有方法digest(消化)
        that.thew++;
      }

      this.eat = function (food) {                    //公有方法eat(吃)
        digest(food);
      }
    }

    /*通过prototype定义的属性和方法都是公有的
     *优点:使用原型对象的最大好处就是,可以按照需要随时对类进行扩展,
     *      而不需要改动原有类的定义
     */
    People.prototype = {
      thew: 1,
      changeName: function (newName) {
        this.name = newName;
      }
    }

    /*通过this指针添加的属性(方法)都是公有属性(方法),也就是可以被外部调用
     *私有属性(方法)只能在对象内部被访问和操作
     */
    var someone = new People("Susan", "female", 1000);
    someone.changeName("Lily");
    console.log(someone.name);                      //Lily
    someone.eat("apple");
    console.log(someone.thew);                      //2

2.继承

对象冒充:是一个对象将另一个对象的方法当作自己的方法来执行。Javascript提供了call和apply两个方法来实现这种机制。call和apply方法所实现的功能是一样的,只是参数形式不同,其语法如下所示:

    functionName.call(object,argument1,argument2,argument3,...);
    functionName.apply(object,[argument1,argument2,argument3,...]);

在call中,实际参数是直接以call方法的参数形式实现,而在apply中,则被放到了一个数组中。

使用对象冒充实现继承,

    function Circle(center,radius){
      Shape.call(this,"circle");                //采用对象冒充的机制来调用父类的构造函数
      this.center=center;
      this.radius=radius;
    }

    var circle=new Circle(10,30);
    var name=circle.getName();
    console.log(name);                          //circle

对象冒充实现了继承,但仍然还有一些缺陷。在使用对象冒充机制来实现继承时,子类只是在构造函数中调用了父类的构造函数,但是没有对父类的原型对象做任何处理,这使得定义在父类原型对象中的属性和方法没有被继承。

    /*
     *通过Function的原型对象添加一个inherit方法,该方法完成继承逻辑的封装
     *接受三个参数:instance:实例,baseClass:基类,arguments:传递给基类构造函数的参数
     */
    Function.prototype.inherit=function(instance,baseClass,arguments){
      this._baseClass=baseClass;                        //给子类添加一个_baseClass属性,保存对基类的引用
      baseClass.apply(instance,arguments);              //使用对象冒充来调用基类的构造函数

      //复制基类原型对象中的属性和方法到子类的原型对象中
      //如果存在同名的属性和方法,则跳过
      for(var memberName in baseClass.prototype){
        var memberValue=baseClass.prototype[memberName];
        if(!this.prototype[memberName]){
          this.prototype[memberName]=memberValue;
        }
      }
    }

    function Shape(name){
      var name=name;
      this.getName=function(){
        return name;
      }
    }

    Shape.prototype={
      draw:function(){
        console.log("drawing...")
      }
    }

    function Circle(center,radius){
      Circle.inherit(this,Shape,["circle"]);      //继承Shape类
      this.center=center;
      this.radius=radius;
    }

    var circle=new Circle(10,30);
    var name=circle.getName();
    console.log(name);                            //circle
    circle.draw();                                //drawing




你可能感兴趣的:(javascript)