首页 > 语言 > JavaScript > 正文

Javascript中类式继承和原型式继承的实现方法和区别之处

2024-05-06 15:18:01
字体:
来源:转载
供稿:网友

在所有面向对象的编程中,继承是一个重要的话题。一般说来,在设计类的时候,我们希望能减少重复性的代码,并且尽量弱化对象间的耦合(让一个类继承另一个类可能会导致二者产生强耦合)。关于“解耦”是程序设计中另一个重要的话题,本篇重点来看看在javascript如何实现继承。

其它的面向对象程序设计语言都是通过关键字来解决继承的问题(比如extend或inherit等方式)。但是javascript中并没有定义这种实现的机制,如果一个类需要继承另一个类,这个继承过程需要程序员自己通过编码来实现。

一、类式继承的实现

1、创建一个类的方式:

//定义类的构造函数function Person(name) {  this.name = name || '默认姓名';}//定义该类所有实例的公共方法Person.prototype.getName = function() {  return this.name;}var smith = new Person('Smith');var jacky = new Person('Jacky');console.log( smith.getName(), jacky.getName() ); //Smith Jacky

2、继承这个类:

这需要分两个步骤来实现,第1步是继承父类构造函数中定义的属性,第2步是继承父类的prototype属性

//定义类的构造函数function Person(name) {  this.name = name || '默认姓名';}//定义该类所有实例的公共方法Person.prototype.getName = function() {  return this.name;}function Author(name, books) {  //继承父类构造函数中定义的属性  //通过改变父类构造函数的执行上下文来继承  Person.call(this, name);  this.books = books;}//继承父类对应的方法Author.prototype = new Person(); //Author.prototype.constructor === PersonAuthor.prototype.constructor = Author; //修正修改原型链时造成的constructor丢失Author.prototype.getBooks = function() {  return this.books;};//测试var smith = new Person('Smith');var jacky = new Author('Jacky', ['BookA', 'BookB']);console.log(smith.getName()); //Smithconsole.log(jacky.getName()); //Jackyconsole.log(jacky.getBooks().join(', ')); //BookA, BookBconsole.log(smith.getBooks().join(', ')); //Uncaught TypeError: smith.getBooks is not a function

从测试的结果中可以看出,Author正确继承了Person,而且修改Author的原型时,并不会对Person产生影响。这其中的关键一句就是 Author.prototype = new Person(),要与Author.prototype = Person.prototype区分开来。前者产生了一个实例,这个实例有Person.prototype的副本(这里先这么理解,后面有更详细的解析)。后者是指将两者的prototype指向同一个原型对象。

那么,这也意味着每次继承都将产生一个父类的副本,肯定对内存产生消耗,但为了类式继承这个内存开销必须得支付,但还可以做得更节省一点:Author.prototype = new Person()这一句其实多执行了构造函数一次(而这一次其实只需在子类构造函数中执行即可),尤其是在父类的构造函数很庞大时很耗时和内存。修改一下继承的方式,如下:

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选