1.为什么要继承
在设计类的时候,总是在强调减少类与类之间的“耦合度”,也就是减少类与类之间的关联。而通过继承能给我们带来什么呢?
1)减少重复性代码
2)弱化对象间的耦合
3)抽象不应该依赖细节;细节应该依赖抽象—《设计模式》
而我们知道像在C#语言中,继承机制操作的话,只需要一个关键字即可,而在javas没有这种机制,还需要模范,下面就是几种模仿继承的方法。
2.原型链式
首先创建一个Person类,其有name属性,然后让一个Author类来继承Person类。效果如下:
<span style="font-family:SimSun;font-size:18px;"> <script> //通过一个构造函数来创建一个Person类 function Person(name) { this.name = name; } //通过原型机制来获取name属性 Person.prototype.getName = function () { alert(this.name); } //创建一个Author类 function Author(name, books) { //调用一个对象的一个方法,以另一个对象替换当前对象。 //这里就是Author会有了Person类name的属性 //也就是Author类有了this.name = name Person.call(this, name); this.books = books; } //使Author类的prototype属性指向Person类 //从这里Author类的prototype也就有了Person类的方法 Author.prototype = new Person(); alert(Author.prototype.constructor);//返回Person Author.prototype.constructor = Author; //刚才prototype属性设置时,constructor被抹除 Author.prototype.getBooks = function () { return this.books; } //创建一个实例对象 var a = new Author("好的", "haode"); //通过继承a也有了Person类的Getname方法 a.getName(); </script></span>
通过上述代码,我们看出为了让Author继承Person,必须手工设置Author的Prototope为Person的实例,最后还需将prototype的constructor的属性设置为author。通过这几步就实现了继承。
我们为何不能像C#中那样直接通过一个关键字就实现继承,也没有了这么多麻烦的操作呢?
3.extend函数
在这种方法中,我们就是把继承子类的整个过程封装到了一个extend函数中,这样就达到了模仿C#那种关键字的效果。既然我们知道了我们需要的操作,直接看代码吧
<span style="font-family:SimSun;font-size:18px;"> //extend函数用来封装那一些列的操作 //参数是要实现继承的两个对象 //subClass代表子类,superClass代表父类 function extend(subClass, superClass) { //声明第三方,通过第三方来实现那一系列的操作 var F = function () { }; //看过上面那个例子,下面这些东东就知道干什么了把 F.prototype = superClass.prototype; subClass.prototype = new F(); subClass.prototype.constructor = subClass; } //通过一个构造函数来创建一个Person类 function Person(name) { this.name = name; } //通过原型机制来获取name属性 Person.prototype.getName = function () { alert(this.name); } //创建一个Author类 function Author(name, books) { //调用一个对象的一个方法,以另一个对象替换当前对象。 //这里就是Author会有了Person类name的属性 //也就是Author类有了this.name = name Person.call(this, name); this.books = books; } //继承的实现操作 extend(Author, Person); Author.prototype.getBooks = function () { return this.books; }</span>
4.原型式继承
我们从上述几种类式继承中看到,每次的操作都需要两个步骤:第一:定义类的结构;第二:实例化该类。而接下来原型式继承时,并不需要这些操作。只需直接创建一个对象,然后这个对象就可以被后面的对象所重用,在这里用到了Clone()的方法。看一下实例
<span style="font-family:SimSun;font-size:18px;"> <script> //定义一个Person对象 var Person = { name: 'default name', getName: function () { return this.name; } }; // var reader = clone(Person); alert(reader.getName()); // reader就有了Person的方法 reader.name = 'John Smith'; alert(reader.getName()); /*Author原型对象*/ var Author = clone(Person); Author.books = []; Author.getBooks = function () { return this.books; } </script></span>
上面的clone函数可以用来创建新的Person对象,它会创建一个空对象,而该对象的原型对象被设置为Person,这就意味着在这个对象中查找某个方法的时候,如果找不到,那么查找过程会在其原型对象中继承进行。
通过这个方法,减少了实例化person子类的操作,只要执行一次克隆即可。
5.小结
本篇博客中主要讲解了几种继承的方法,可以分为两种:类式继承和原型式继承。区别在原型式继承更能节约内存,因为正如上述代码所示所有克隆出来的对象都共享每个属性和方法,而且通过clone方法也减少了许多麻烦的操作。当然到底使用哪种继承方式主要取决于你更喜欢哪种类型。
以上代码中涉及到javascript中call方法、constructor与prototype。详细的内容请参见一下博客。