js 继承是在前端面试及js库开发中常常遇到的问题。在面向对象开发时继承知识也是很是重要,本人阅读了一些文章总结了js继承的要点,但愿能对你们有所帮助。前端
通俗的说:某一个工程须要蓝图实现来工程,蓝图就是类
。但在一个新工程的蓝图设计时须要复制一些老蓝图上的工程经验来提高效率,这个过程就至关于继承。面试
//父类 function SuperClass() { this.superValue = true; } SuperClass.prototype.getSuperValue = function() { return this.superValue; } //子类 function SubClass() { this.subValue = false; } SubClass.prototype = new SuperClass(); SubClass.prototype.getSubValue = function() { return this.subValue; } var instance = new SubClass(); console.log(instance instanceof SuperClass)//true console.log(instance instanceof SubClass)//true console.log(SubClass instanceof SuperClass)//false
这种方式是最原始的方式,使用父类的一个实例重写到子类原型对象上,从而实现父类成员的继承,有点继承的样子,可是总以为怪怪的,你肯定把一个实例赋值到原型上真的没有问题吗?数组
缺点:浏览器
SubClass.prototype = new SuperClass();
重写语句以后,很不方便function SuperClass(id) { this.books = ['a','b']; this.id = id; } SuperClass.prototype.showBooks = function() { console.log(this.books); } function SubClass(id) { //继承父类 SuperClass.call(this,id); } var instance1 = new SubClass(10); var instance2 = new SubClass(11); instance1.books.push('c'); console.log(instance1) console.log(instance2) instance1.showBooks();
比上面一个稍微好了一点,也能传参了,每次出来的数组也是惟一的了。原理是在子类构造的时候使用call的特性借用一下父类的构造函数,把父类的成员都设置在子类中来实现继承。额。。那原型呢?
缺点:函数
function SuperClass(name) { this.name = name; this.books = ['A','B']; } SuperClass.prototype.getBooks = function() { console.log(this.books); } function SubClass(name,time) { SuperClass.call(this,name); this.time = time; } SubClass.prototype = new SuperClass(); SubClass.prototype.getTime = function() { console.log(this.time); }
还能够,能用,原理也就是结合了以上两种(构造函数、类式继承)的继承方式,并修复了严重的缺点。之前应该用这种方法的人也比较多吧
缺点:this
function inheritObject(o) { //声明一个过渡对象 function F() { } //过渡对象的原型继承父对象 F.prototype = o; //返回过渡对象的实例,该对象的原型继承了父对象 return new F(); } var book = { name:'A book', likeBook:['B Book','C book'] } var newBook = inheritObject(book); newBook.name = 'AA1 book'; newBook.likeBook.push('CC book'); var otherBook = inheritObject(book); otherBook.name = 'EE book'; otherBook.likeBook.push('FF book'); console.log(newBook,otherBook);
这就像类式继承同样,直接把父的成员放到子类的原型上,经过原型链来实现继承。inheritObject就像是object.create()和new的模拟实现,产出很是纯净的对象。
黑人问号.jpg。使用这种方法意思是放弃了构造函数来实现继承?
缺点:prototype
var book = { name:'A book', likeBook:['B book','C book'] } function createBook(obj) { //经过原型方式建立新的对象 var o = new inheritObject(obj); // 拓展新对象 o.getName = function(name) { console.log(name) } // 返回拓展后的新对象 return o; }
依然保留了inheritObject函数来实现父成员的继承,相比上面的原型继承代码更有组织性了,单独封装了一个函数来实现继承,而后使用原型继承来继承对应的父类
缺点:
已经差很少作到了继承,可是原型继承问题依然没有解决设计
function inheritObject(o) { function F() { } F.prototype = o; return new F(); } function inheritPrototype(subClass,superClass) { // 复制一份父类的原型副本到变量中 var p = inheritObject(superClass.prototype); // 修正由于重写子类的原型致使子类的constructor属性被修改 p.constructor = subClass; // 设置子类原型 subClass.prototype = p; } //继承 function SuperClass(name) { this.name = name; this.books=['a book','b book']; } SuperClass.prototype.getName = function() { console.log(this.name); } function SubClass(name,time) { SuperClass.call(this,name); this.time = time; } inheritPrototype(SubClass,SuperClass); SubClass.prototype.getTime = function() { console.log(this.time); } var instance1 = new SubClass('f1','2017') var instance2 = new SubClass('r2','2018'); instance1.books.push('new book'); console.log(instance1,instance2);
继承终极版。这个继承方式是在解决组合继承遇到的问题,先给子类链接上纯净的父原型成员,而后再借用父类构造函数获取到父构造函数里的成员,基本解决上面出现的问题。code
剩下没说的就是ES6的继承,也是至关于一个ES6的语法糖,源码也是基于寄生组合式继承。缺点就是对低版本的浏览器不友好, 以上总结了6种js继承方式,每个继承方式都是修复以前继承的不足,重点是理解它们的特色和之间的差别,弄明白为何要这样作,这样才能完全理解js继承的内容。最后,但愿能对你有帮助~对象