在我的前两篇文章中,我们已经介绍了 js 中实现继承的两种模式:原型链继承借用构造函数继承。这两种模式都存在各自的缺点,所以,我们考虑是否能将这二者结合到一起,从而发挥二者之长。即在继承过程中,既可以保证每个实例都有它自己的属性,又能做到对一些属性和方法的复用。这样就 perfect 了。

一、回顾借用构造函数继承的缺点

先看我们之前在借用构造函数继承中最后用到的代码:

    //父类:人
function Person () {
this.head = '脑袋瓜子';
this.emotion = ['喜', '怒', '哀', '乐']; //人都有喜怒哀乐
this.eat = function () {
console.log('吃吃喝喝');
}
this.sleep = function () {
console.log('睡觉');
}
this.run = function () {
console.log('快跑');
}
}
//子类:学生,继承了“人”这个类
function Student(studentID) {
this.studentID = studentID;
Person.call(this);
} //Student.prototype = new Person(); var stu1 = new Student(1001);
console.log(stu1.emotion); //['喜', '怒', '哀', '乐'] stu1.emotion.push('愁');
console.log(stu1.emotion); //["喜", "怒", "哀", "乐", "愁"] var stu2 = new Student(1002);
console.log(stu2.emotion); //["喜", "怒", "哀", "乐"]

  

  在这段代码中,我们通过借用构造函数继承,保证了 stu1 和 stu2 都有各自的父类属性副本,从而使得各自 emotion 互不影响。但同时带来的问题是,stu1 和 stu2 都拷贝了 Person 类中的所有属性和方法,而在 Person 类中,像 eat ( ), sleep ( ), run ( ) 这类方法应该是公用的,而不需要添加到每个实例上去,增大内存,尤其是这类方法较多的时候。

二、结合使用两种继承模式

  所以我们想到,是否能把这些方法挂载到父类的原型对象上去,实现方法复用,然后子类通过原型链继承,就能调用这些方法啦?~

    //父类:人
function Person () {
this.head = '脑袋瓜子';
this.emotion = ['喜', '怒', '哀', '乐']; //人都有喜怒哀乐
}
//将 Person 类中需共享的方法放到 prototype 中,实现复用
Person.prototype.eat = function () {
console.log('吃吃喝喝');
}
Person.prototype.sleep = function () {
console.log('睡觉');
}
Person.prototype.run = function () {
console.log('快跑');
}
//子类:学生,继承了“人”这个类
function Student(studentID) {
this.studentID = studentID;
Person.call(this);
} Student.prototype = new Person(); //此时 Student.prototype 中的 constructor 被重写了,会导致 stu1.constructor === Person
Student.prototype.constructor = Student; //将 Student 原型对象的 constructor 指针重新指向 Student 本身 var stu1 = new Student(1001);
console.log(stu1.emotion); //['喜', '怒', '哀', '乐'] stu1.emotion.push('愁');
console.log(stu1.emotion); //["喜", "怒", "哀", "乐", "愁"] var stu2 = new Student(1002);
console.log(stu2.emotion); //["喜", "怒", "哀", "乐"] stu1.eat(); //吃吃喝喝
stu2.run(); //快跑
console.log(stu1.constructor); //Student

  首先,我们将 Person 类中需要复用的方法提取到 Person.prototype 中,然后设置 Student 的原型对象为 Person 类的一个实例,这样 stu1 就能访问到 Person 原型对象上的属性和方法了。其次,为保证 stu1 和 stu2 拥有各自的父类属性副本,我们在 Student 构造函数中,还是使用了 Person.call ( this ) 方法。如此,结合原型链继承和借用构造函数继承,就完美地解决了之前这二者各自表现出来的缺点。

 

如果你觉得文章解决了你的疑惑的话,还请赏我一个推荐哦~  :)

作者不才,文中若有错误,望请指正,避免误人子弟。

文章内容全都参考于《JAVASCRIPT 高级程序设计》第三版)

最新文章

  1. well属性
  2. 存储构造题(Print Check)
  3. 01、手把手Android攻城入门
  4. Eclipse中web-inf和meta-inf文件夹的信息
  5. The Ninth Hunan Collegiate Programming Contest (2013) Problem H
  6. ChRoomtst
  7. Linux是一门真正的黑客高手艺术
  8. Android 5.1 Camera 架构学习之Camera初始化
  9. 【Java GUI】Java GUI基金会
  10. python变量与数据类型
  11. STL部分的实现
  12. 【Maven】 install:install-file
  13. python day09
  14. [Swift]LeetCode216. 组合总和 III | Combination Sum III
  15. java之try、catch、finally
  16. SQL语句执行的顺序机制
  17. openssl、x509、crt、cer、key、csr、ssl、tls process
  18. memcache缓存失效
  19. debian修改时区
  20. 【Nginx】均衡负载权重模式实现session数据同步

热门文章

  1. Day11 数据库的基本语法(偏重于查询)
  2. php添加日志文件
  3. Kali学习笔记4:Wireshark详细使用方法
  4. 使用pypi-server搭建简单的PyPI源
  5. 3、js无缝滚动轮播
  6. 更新版PowerBI发布了-- Power BI Report Server Update – March 2018
  7. 如何在Visual Studio和CodeBlocks中反编译C++代码
  8. Jmeter性能测试 如何利用SQLserver造出大批的数据
  9. Markdown 编辑器语法 专题
  10. 深浅拷贝,原生和JQuery方法实现