设计类的时候我们都希望减少重复性的代码,并且弱化对象间的耦合,这也是继承能带来的好处。担心继承也有缺点,让一个类继承另一个类会导致两者产生强耦合。我们将讨论一些有助于避免这种问题的技术,以下三种继承:
1,类式继承
首先创建构造函数
function Person(name) { this.name = name; } Person.prototype.getName = function() { return this.name; } var reader = new Person('John Smith'); reader.getName();
原型链继承父类Person
function Author(name,books){ Person.call(this,name); this.books = books; } Author.prototype = new Person(); Author.prototype.constructor = Author; //这里有个需要特别指出的地方,当Author的原型指向Person的一个实例时,它的构造函数不在指向它自己,需要手动设为Auther Author.prototype.getbooks = function() { return this.books; }
可以使用extend方法来统一继承分类的原型方法和属性
function extend(subClass, superClass) { var F = function() {}; F.prototype = superClass.prototype; subClass.prototype = new F(); subClass.prototype.constructor = subClass; subClass.superclass = superClass.prototype; if(superClass.prototype.constructor == Object.prototype.constructor) { superClass.prototype.constructor = superClass; } }
总结类式继承的代码
function Author(name, books) { Author.superclass.constructor.call(this, name); this.books = books; } extend(Author, Person); Author.prototype.getBooks = function() { return this.books; }; Author.prototype.getName = function() { var name = Author.superclass.getName.call(this); return name + ', Author of ' + this.getBooks().join(', '); };
2,原型式继承
function clone(object){ function F(){}; F.prototype = object; return new F; } var Person = { name: 'default name', getName: function() { return this.name; } }; var reader = clone(Person); //继承单一模式的对象字面量父类
相比类式继承,原型继承更能节约内存,因为在类式继承方式中每一个对象在内存中都有自己的一套私有属性和方法。原型继承相对更为简练。
3,掺元类
function augment(receivingClass, givingClass) { if(arguments[2]) { // Only give certain methods. for(var i = 2, len = arguments.length; i < len; i++) { receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]]; } } else { // Give all methods. for(methodName in givingClass.prototype) { if(!receivingClass.prototype[methodName]) { receivingClass.prototype[methodName] = givingClass.prototype[methodName]; } } } } var Person = function(){}; Person.prototype = { name: 'default name', getName: function() { return this.name; } }; function Author(books){ this.books = books; } augment(Author,Person); var au = new Author('hhh')
掺元类更适用于扩充一个类,这是一种避免出现重复性代码的轻便的解决办法。