JavaScript面向对象的编程

 关于JavaScript面向对象的编程以下是我的理解,有不对的地方请指出;

JavaScript是一种基于对象的语言,遇到的东西几乎都是对象,但又不是完整的面向对象的语言,因为他的语法中没有类(class) ,使用中我们可以吧属性和方法封装成一个对象,有时候也会从原型对象中生成一个实例对象。我们可以通过下面代码实现:

我们先把猫看作一个对象,它有两个属性 : 颜色和名字 

var  cat ={

    name :"",
    color: ""
}


我们可以根据这个原型对象生成两个实例对象 

     var cat1 = {}; // 创建一个空对象
     cat1.name = "大毛";       // 按照原型对象的属性赋值
     cat1.color = "黄色";
  var cat2 = {};
       cat2.name = "二毛";
     cat2.color = "黑色";



这就是简单的封装了,把两个属性封装在一个对象里面。但是,这样的写法有两个缺点,一是如果多生成几个实例,写起来就非常麻烦;二是实例与原型之间,没有任何办法,可以看出有什么联系。

 我们还可以用构造函数的模式,构造函数其实就是一个普通函数,但是在它内部使用了this变量,我们再用new对函数进行实例化,this变量也会绑定在实例对象上。

function Cat(name,color){
    this.name=name;
    this.color=color;
  }



我们可以用new运算符生成实例对象

var cat1 = new Cat("大毛","黄色");
  var cat2 = new Cat("二毛","黑色");
  alert(cat1.name); // 大毛
  alert(cat1.color); // 黄色
 

cat1和cat2 会自动含有constructor指向他们的构造函数

      
      alert(cat1.constructor == Cat); //true
  alert(cat2.constructor == Cat); //true
   

我们还可以为cat添加不变的属性,比如type或者添加一个eat()方法,在这我们用一种节省内存的方法 来做,将不变的属性和方法直接定义到prototype对象上。

function Cat(name,color){
    this.name = name;
    this.color = color;
  }
  Cat.prototype.type = "猫科动物";
  Cat.prototype.eat = function(){alert("吃老鼠")};

然后我们可以生成实例

var cat1 = new Cat("大毛","黄色");
  var cat2 = new Cat("二毛","黑色");
  alert(cat1.type); // 猫科动物
  cat1.eat(); // 吃老鼠
 

对于构造函数的继承我们说两种方法,一个是 prototype模式,一个是直接继承prototype对第一种的改进

有一个动物的构造函数
function Animal(){
    this.species = "动物";
  }
还有一个"猫"对象的构造函数。

  function Cat(name,color){
    this.name = name;
    this.color = color;
  }

 

 现在用第一种方法继承 

    Cat.prototype = new Animal();
  Cat.prototype.constructor = Cat;
  var cat1 = new Cat("大毛","黄色");
  alert(cat1.species); // 动物
Cat.prototype = new Animal();

 

代码的第一行,我们将Cat的prototype对象指向一个Animal的实例。

相当于完全删除了prototype 对象原先的值,然后赋予一个新值。

Cat.prototype.constructor = Cat;

  

第二行的意思是任何一个prototype对象都有一个constructor属性,指向它的构造函数。如果没有"Cat.prototype = new Animal();"这一行,Cat.prototype.constructor是指向Cat的;加了这一行以后,Cat.prototype.constructor指向Animal。

 验证一下

alert(Cat.prototype.constructor == Animal); //true

 

每一个实例也有一个constructor属性,默认调用prototype对象的constructor属性

alert(cat1.constructor == Cat.prototype.constructor); // true

 

因此,在运行"Cat.prototype = new Animal();"这一行之后,cat1.constructor也指向Animal!所以我们要注意使用第二行,改constructor的值 

还有一种就是 直接继承prototype,这是对上一种方法的改进,由于Animal对象中,不变的属性都可以直接写入Animal.prototype。所以,我们也可以让Cat()跳过 Animal(),直接继承Animal.prototype。

我们先将Animal对象改写

 function Animal(){ }
  Animal.prototype.species = "动物";

 

将Cat的prototype对象,然后指向Animal的prototype对象,这样就完成了继承。

 

    Cat.prototype = Animal.prototype;
  Cat.prototype.constructor = Cat;
  var cat1 = new Cat("大毛","黄色");
  alert(cat1.species); // 动物

但是我们要注意的是第二行实际上把Animal.prototype对象的constructor属性也改掉了

  alert(Animal.prototype.constructor); // Cat

 

猜你喜欢

转载自1397548794.iteye.com/blog/2413401