JavaScript构造函数继承的几个方法

js构造函数中的五种继承方法

两个对象的构造函数,动物类
function Animal(){
    this.species = "动物";
  }
function Cat(name,color){
    this.name = name;
    this.color = color;
  }
怎么让猫继承动物类呢?有五种方法供我们使用
一、构造函数方法
用call或者apply方法将父对象的构造函数绑定在子函数身上
function Cat(name,color){
    	// 将animal实例构造函数绑定到子函数上
    	Animal.apply(this,arguments);
    	this.name=name;
    	this.color=color;
    	var cat1 = new Cat("大毛","黄色");
  	alert(cat1.species); // 动物
    }

  

二、prototyp模式

function Animal(){
	    this.species = "动物";
	  }
	function Cat(name,color){
    this.name = name;
    this.color = color;
  }
   // console.log(Cat.prototype);出现的是一个object对象,其构造函数指向Cat
    //console.log(Cat.constructor);出现的是一个空的函数定义,因为Cat类似于一个实例对象,而cat.prototype才指向原型对象
    //console.log(Cat.prototype.constructor);出现的是cat原型的函数定义
    Cat.prototype=new Animal();//相当于是将animal设置成了cat原型的原型
    //console.log(Cat.prototype);出现的是一个anima对象,构造函数是animal()
    //console.log(Cat.constructor);任然是一个空的函数定义,因为第一句相当于删除了prototype属性
    //console.log(Cat.prototype.constructor);出现的是function animal,因为将Cat.prototype指向了animal
    Cat.prototype.constructor=Cat;
    //原本Cat.prototype.constructor指向的是cat,而Cat.prototype=new Animal();将Cat的原型指向了animal,所以此时Cat.prototyp
    //e.constructor将会等于animal,这样会导致继承连的紊乱,所以需要手动纠正
    //console.log(Cat.prototype);出现animal对象,constructo指向cat,所以继承成功
    //console.log(Cat.constructor);
    //console.log(Cat.prototype.constructor);
    // var cat1 = new Cat("大毛","黄色");
    // alert(cat1.constructor == Animal);

  

这显然会导致继承链的紊乱(cat1明明是用构造函数Cat生成的),因此我们必须手动纠正,将Cat.prototype对象的constructor值改为Cat。这就是第二行的意思。
这是很重要的一点,编程时务必要遵守。下文都遵循这一点,即如果替换了prototype对象,
  o.prototype = {};
那么,下一步必然是为新的prototype对象加上constructor属性,并将这个属性指回原来的构造函数。
  o.prototype.constructor = o;
 
三,直接继承prototype
由于prototype属性可以直接保存不变的属性,所以我们只需要设置
function Animal(){ }
Animal.prototype.species = "动物";
Cat.prototype = Animal.prototype;
Cat.prototype.constructor = Cat;
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物

上述即可,但是这样做有一个缺点,因为cat和animal原型指向了一个对象即Cat.prototype = Animal.prototype;所以任何对cat.prototype的修改也会影响到Animal(类似指针)

 

四。YUI框架的写法(利用空对象进行拷贝)

var F = function(){};
F.prototype = Animal.prototype;
Cat.prototype = new F();
Cat.prototype.constructor = Cat;

 

利用中间变量F保存了Animal.prototype,然后将cat设置为F的实例,所以Cat.prototype的修改相当于是F实例的修改,然不会改变Animal.prototype的值,而且F为空,几乎不占内存,然后将上述封装成一个函数

 

function extend(Child, Parent) {
    var F = function(){};
    F.prototype = Parent.prototype;
    Child.prototype = new F();
    Child.prototype.constructor = Child;
    Child.uber = Parent.prototype;
  }
extend(Cat,Animal);
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物

还有一种不常用,不做介绍了。

ps:不知道为什么copy过来的代码会出现格式紊乱

posted @ 2017-03-07 20:32  老夫代码复制粘贴  阅读(311)  评论(0)    收藏  举报