首页 > 代码库 > js继承
js继承
前面几天说了下js种的单例模式,以及观察者的单例对象,从中发现,有些比较复杂的功能,或者需要重复使用的功能单例有点捉襟见肘,但是在一些有着共同性得基础上衍生新功能或者实现不同得功能得时候,我们就可以用到继承了。继承可以减少重复性的代码,并且尽量弱化类之间的耦合。
继承的实现就是将子类原型指向父类的一个对象实例,为什么不是直接指向父类的原型呢?因为父类原型是一个引用类型,直接指向的话,修改子类原型的同时也修改了父类,这是不允许的.首先我们定义一个继承函数:
function inherit(parentClass,sonClass){ var F = function(){}; F.prototype = parentClass.prototype; sonClass.prototype = new F(); sonClass.prototype.constructor=sonClass; }
可以看到在里面我们新建了一个空函数,并将空函数的原型指向父类的原型。为什么要这样呢,为什么不是sonClass.protype=new parentClass()呢?因为有可能父类会比较庞大,而且父类的构造函数会有一些副作用,或者说会执行大量的计算任务。总的来说这段代码实现了子类对父类的继承,函数内部先创建了一个空对象,空对象的原型指向父类的原型,然后子类的原型指向这个空对象的一个实例,再将子类的constructor属性指向子类。对象的constructor属性用于返回创建该对象的函数,也就是我们常说的构造函数。接下来创建父类与子类函数了。
1 function Maple(name){ 2 this.name=name; 3 } 4 Maple.prototype={ 5 sayHello:function(){ 6 console.log("hello world"); 7 }, 8 sayName:function(){ 9 console.log("my name is "+ this.name); 10 } 11 }; 12 13 function Tao(name){ 14 Maple.call(this,name); 15 } 16 inherit(Maple,Tao); 17 18 Tao.prototype.sayGoodBye=function(){ 19 console.log("goodBye"); 20 };
上面定义了一个父类函数Maple,子类元素Tao,在子类元素种通过call方法去调用父类的构造函数,这里需要注意点,就是在扩张子类原型之前得先实现继承,要不然在后面会把原型覆盖,而且子类原型添加必须使用点式添加,即sonClass.protype.a。定义好了接下来就是简单得调用了。
var tao=new Tao("tao");
console.log(tao)
tao.sayHello();
tao.sayName();
tao.sayGoodBye();
从上面Tao这个结构可以看出,该实例对象既实现自己原型上得方法,而且也能找到父类得方法,补充下,子类去找方法的时候是一级一级去找的,当找到了就不会去找后面原型上的了,这样在有需求的时候我们就可以去重写父类的方法了。
关于继承,父类可以是一个有着相似功能的一个基类,里面定义了最基本的实现方法,在子类中可以通过扩展强大这个功能,或者实现不同形式的功能,比如轮播图,继承可以让代码的复用性更强。
js继承