JavaScript面向对象轻松入门之继承(demo by ES五、ES6)

  继承是面向对象很重要的一个概念,分为接口继承和实现继承,接口继承即为继承某个对象的方法,实现继承即为继承某个对象的属性。JavvaScript经过原型链来实现接口继承、call()apply()来实现实现继承。浏览器

  接口继承的实如今ES5中是比较麻烦,在其它OOP语言中一个extends关键字就能够实现,但在ES5中要经过原型链去模拟,很是难理解,对初学者很不友好,而且有好几种接口继承的方式。本文为了对初学者更友好,并不打算让读者了解接口继承的原理,而是直接把接口继承实现方法封装成一个函数,你们只要把这个函数拿过去用就能够了。app

  相关概念:父类(超类)即为被继承者,子类(派生类)即继承者函数

接口继承函数extend():

 1 function extend(subClass, superClass) {
 2     function o() {
 3         this.constructor = subClass;
 4     }
 5     o.prototype = superClass.prototype;
 6     subClass.prototype = new o();
 7     return subClass.prototype;
 8 }
 9 /*
10 subClass是子类,superClass是父类,extend函数让subClass继承superClass的原型方法,并返回subClass的原型;
11 这种继承方式也是用的最多的,而且ES6的extends也是经过这种方式实现的,能够说是比较权威的用法;
12 */

ES5继承DEMO:

 1 function Animal(shoutVoice,speed){
 2     this._shoutVoice = shoutVoice;//string
 3     this._speed = speed;//string
 4 }
 5 Animal.prototype.getSpeed = function(){
 6     return this._speed;
 7 };
 8 Animal.prototype.shout = function(){
 9     console.log(this._shoutVoice);
10 };
11 Animal.prototype.run = function(){
12     console.log('嘿嘿,吃我灰吧!个人速度但是有'+this._speed);
13 };
14 
15 function Dog(){
16     Animal.call(this,'汪汪汪!','10m/s');
17     //实现继承:调用Animal的构造函数,继承Animal类的属性,第一个参数必须是this;
18 }
19 //接口继承:extends函数让Dog类继承Animal类的的原型方法并返回Dog的新的原型prototype;
20 var DogP = extend(Dog,Animal);
21 /*能够继续给的Dog类的prototype添加方法*/
22 DogP.gnawBone = function() {
23     console.log('这是本狗最幸福的时候');
24 }
25 /*也能够把父类的方法覆盖掉*/
26 DogP.run = function(){
27     console.log('这是Dog类上的run方法,不是Animal类的');
28     /*虽然覆盖掉了,但实际上Animal类的run方法还在,也能够经过这种方式访问父类的方法,
29     对原理有兴趣的同窗能够了解一下原型链*/
30     Animal.prototype.run.call(this);
31 }
32 var dog = new Dog();
33 console.log(dog.getSpeed());//log: '10m/s'
34 dog.shout();//log: '汪汪汪!'
35 dog.run();
36 /*log:
37 '这是Dog类上的run方法,不是Animal类的'
38 '嘿嘿,吃我灰吧!个人速度但是有10m/s'
39 */
40 dog.gnawBone();//log: '这是本狗最幸福的时候'42 /*其它类继承Animal类*/
43 function Snake(){
44     Animal.call(this,'嘶!嘶!嘶!','5m/s');
45 }
46 var SnakeP = extend(Snake,Animal);
47 /*Dog类也能够继续被继承*/
48 function PoodleDog(){
49     Dog.call(this);
50     this._breed = 'poodle';
51 }
52 var PoodleDogP = extend(PoodleDog,Dog);
53 /*理论上讲能够无限继承下去,如浏览器DOM对象就继承了不少个对象,组成了一个长长的原型链
54 如一个div标签对象的类继承顺序:
55 HTMLDivElement<HTMLElement<Element<Node<EventTarget<Object
56 但咱们的项目中最好别超过3次,不然就不太好控制了;*/

注意事项:

  *继承的次数不该过多,不然子类一不当心就把父类的属性方法给覆盖了;
  *咱们能够把继承的对象做为成员属性,即组合,尽可能少用继承,多用组合;
  *父类的属性和方法最好别太多,过多也容易被子类覆盖,能够抽象成一个对象来管理过多的属性和方法。
  *继承增长了耦合,因此父类封装性必定要好,尽可能下降与子类的耦合,
  *父类的设计要有前瞻性,具有必定的扩展能力,你也不但愿从此修改父类的时候,再去修改全部的子类吧?this

  *父类尽可能只定义方法,不定义属性,即构造函数最好是空函数;spa

ES6继承DEMO:

  ES6实现继承就方便不少了,因为TypeScript实现继承和ES6差很少,因此这章就不贴出TypeScript的Demo了prototype

 1 class Animal{
 2     constructor(shoutVoice,speed){
 3         this._shoutVoice = shoutVoice;//string
 4         this._speed = speed;//string
 5     }
 6     get speed(){
 7         return this._speed;
 8     }
 9     shout(){
10         console.log(this._shoutVoice);
11     }
12     run(){
13         console.log('嘿嘿,吃我灰吧!个人速度但是有'+this._speed);
14     }
15 }
16 class Dog extends Animal{
17     constructor(){
18         super('汪汪汪!','10m/s');//至关于Animal.call(this,'汪汪汪!','10m/s');
19     }
20     gnawBone() {
21         console.log('这是本狗最幸福的时候');
22     }
23     run(){
24         console.log('这是Dog类上的run方法,不是Animal类的');
25         super.run();//至关于Animal.prototype.run.call(this);
26     }
27 }
28 class PoodleDog extends Dog{
29     constructor(){
30         super();
31         this._breed = 'poodle';
32     }
33     get breed(){
34         return this._breed;
35     }
36 }
37 let poodleDog = new PoodleDog();
38 console.log(poodleDog.breed);//log: 'poodle'
39 console.log(poodleDog.speed);//log: '10m/s'
40 poodleDog.shout();//log: '汪汪汪!'
41 poodleDog.run();
42 /*log:
43 '这是Dog类上的run方法,不是Animal类的'
44 '嘿嘿,吃我灰吧!个人速度但是有10m/s'
45 */
46 poodleDog.gnawBone();//log: '这是本狗最幸福的时候'

后话

  js的继承与其它OOP语言有一些不一样的地方,因此最终仍是要深入的理解原型、原型链才能灵活运用,但愿你们有时间必定要把这部分知识补上;设计

  若是你喜欢做者的文章,记得收藏,你的点赞是对做者最大的鼓励;code

  做者会尽可能每周更新一章,下一章是讲多态;对象

  你们有什么疑问能够留言或私信做者,做者尽可能第一时间回复你们;blog

  若是老司机们以为那里能够有不恰当的,或能够表达的更好的,欢迎指出来,我会尽快修正、完善。

相关文章
相关标签/搜索