一、原型链继承

Parent.prototype.grand = 'grand';function Parent (name) {this.name = name || 'parent';this.color = ['red', 'orange', 'yellow'];}function Child () {}Child.prototype = new Parent();var child1 = new Child('child1');var child2 = new Child('child2');

缺点

1.引用值共享问题
引用值会被所有的实例(这里以两个为例,下面也将都是)共享,一个对象修改了原型属性,那么另一个的原型属性也会被修改

2.不能传参
在创建Child的实例时,不能向Parent传递参数;如果传递也不会有作用


二、借用构造函数(经典继承)

 Parent.prototype.grand = 'grand';function Parent (name) {this.name = name || 'parent';this.color = ['red', 'orange', 'yellow'];}function Child (name,) {Parent.call(this, name);}var child1 = new Child('child1');var child2 = new Child('child2');

优点

1.解决了引用值共享的问题

2.可以通过Child向Parent传参

缺点

1.多执行了一次函数 call

2.Parent上的原型不能被继承

注:为了证明Parent的原型上有grand这个属性值,我在控制台新建了一个parent对象


三、组合继承(伪经典继承)

将原型链继承和借用构造函数阶乘结合在一起

Parent.prototype.grand = 'grand';function Parent(name) {this.name = name || 'parent';this.color = ['red', 'orange', 'yellow'];
}function Child(name, age) {Parent.call(this, name);this.age = age;
}Child.prototype = new Parent();
Child.prototype.constructor = Child;var child1 = new Child('child1', 18);
var child2 = new Child('child2', 19);

优点(结合了原型链继承和构造函数继承的优点)

1.Parent上的原型可以被继承

2.解决了引用值共享的问题

3.可以通过Child向Parent传参

缺点

函数多执行了一次call


四、原型式继承

    var car = {name : 'car',color : ['red', 'orange', 'yellow']}function object (o) {function F () {};F.prototype = o;return new F();}var car1 = object(car);var car2 = object(car);

重点:用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象。object.create()就是这个原理。

特点:类似于复制一个对象,用函数来包装。

缺点:1、所有实例都会继承原型上的属性。

2、无法实现复用。(新实例属性都是后面添加的)


五、寄生式继承

     function createObject (o) {var clone = Object.create(o);// var clone = object(o);clone.sayHi = function () {console.log('hi');}return clone;}var car = {name : 'car',color : ['red', 'orange', 'yellow']}var car1 = createObject(car);

重点:就是给原型式继承外面套了个壳子。

优点:没有创建自定义类型,因为只是套了个壳子返回对象(这个),这个函数顺理成章就成了创建的新对象。

缺点:没用到原型,无法复用。


六、寄生组合式继承

为了方便大家阅读,在这里重复一下组合继承的代码:

function Parent (name) {this.name = name;this.colors = ['red', 'blue', 'green'];
}Parent.prototype.getName = function () {console.log(this.name)
}function Child (name, age) {Parent.call(this, name);this.age = age;
}Child.prototype = new Parent();var child1 = new Child('kevin', '18');console.log(child1)

组合继承最大的缺点是会调用两次父构造函数。

一次是设置子类型实例的原型的时候:

Child.prototype = new Parent();
一次在创建子类型实例的时候:

var child1 = new Child(‘kevin’, ‘18’);
回想下 new 的模拟实现,其实在这句中,我们会执行:

Parent.call(this, name);
在这里,我们又会调用了一次 Parent 构造函数。

所以,在这个例子中,如果我们打印 child1 对象,我们会发现 Child.prototype 和 child1 都有一个属性为colors,属性值为[‘red’, ‘blue’, ‘green’]。

那么我们该如何精益求精,避免这一次重复调用呢?

如果我们不使用 Child.prototype = new Parent() ,而是间接的让 Child.prototype 访问到 Parent.prototype 呢?

看看如何实现:


function Parent (name) {this.name = name;this.colors = ['red', 'blue', 'green'];
}Parent.prototype.getName = function () {console.log(this.name)
}function Child (name, age) {Parent.call(this, name);this.age = age;
}// 关键的三步
var F = function () {};F.prototype = Parent.prototype;Child.prototype = new F();var child1 = new Child('kevin', '18');console.log(child1);
最后我们封装一下这个继承方法:function object(o) {function F() {}F.prototype = o;return new F();
}function prototype(child, parent) {var prototype = object(parent.prototype);prototype.constructor = child;child.prototype = prototype;
}// 当我们使用的时候:
prototype(Child, Parent);

ps:建议去看下红宝石书

6种继承的优点和缺点相关推荐

  1. C++ 中的三种继承public , protected, private

    三种访问权限 public:可以被任意实体访问 protected:只允许子类及本类的成员函数访问 private:只允许本类的成员函数访问 三种继承方式 public 继承 protect 继承 p ...

  2. C++中的三种继承public,protected,private(转)

    三种访问权限 public:可以被任意实体访问 protected:只允许子类及本类的成员函数访问 private:只允许本类的成员函数访问 三种继承方式 public 继承 protect 继承 p ...

  3. 理解JS的6种继承方式

    [转]重新理解JS的6种继承方式 写在前面 一直不喜欢JS的OOP,在学习阶段好像也用不到,总觉得JS的OOP不伦不类的,可能是因为先接触了Java,所以对JS的OO部分有些抵触. 偏见归偏见,既然面 ...

  4. 不同级别成员对应三种继承的结果:

    怎么解释呢? 首先,private,私有的,这是绝对的,不会受继承而变化,只对本类(即使是基类)可见. 剩下的public和 protected 成员,三种继承,2×3 = 6.私有继承在派生类中全为 ...

  5. C++继承机制(一)——基本语法、三种继承方式、继承哪些数据

    目录: C++继承机制(一)--基本语法.三种继承方式.继承哪些数据 C++继承机制(二)--继承中的构造和析构顺序.继承同名成员的处理方式 C++继承机制(三)--多继承.菱形继承.虚继承原理 本篇 ...

  6. js的5种继承方式——前端面试

    js主要有以下几种继承方式:对象冒充,call()方法,apply()方法,原型链继承以及混合方式.下面就每种方法就代码讲解具体的继承是怎么实现的. 1.继承第一种方式:对象冒充 1 function ...

  7. protect 继承_c++三种继承方式public,protect,private

    三种访问权限 public:可以被任意实体访问 protected:只允许子类及本类的成员函数访问 private:只允许本类的成员函数访问 三种继承方式 public 继承 protect 继承 p ...

  8. javascript 的七种继承方式(三)组合继承

    组合继承 前面两篇我们了解到:原型链继承存在着引用类型问题,而借用构造函数又无法实现函数复用和原型方法继承的问题.那么能不能把两者结合一下,取其精华,弃其糟粕?答案是肯定的.那就是接下来我们要介绍的组 ...

  9. js常见的的6种继承方式

    继承是面向对象的,继承可以帮助我们更好的复用以前的代码,缩短开发周期,提高开发效率:继承也常用在前端工程技术库的底层搭建上,在整个js的学习中尤为重要 常见的继承方式有以下的六种 一.原型链继承 原型 ...

  10. JavaScript高级第2天:定义函数的三种方式、函数的原型链结构、完整原型链、作用域以及作用域链、函数的四种调用模式、闭包、计数器、斐波那契数列优化、三种继承方式

    JavaScript高级第二天 01-定义函数的三种方式 1.函数声明 function:可以先调用再声明,因为预解析(把函数声明.变量声明进行提升) function fn() {//函数体conl ...

最新文章

  1. java初学者笔记总结day9
  2. 数据库维护优化及后期改进约定.实践篇
  3. 如果往错误的NEO地址转账会发生什么
  4. 第8集析构函数中抛出的异常
  5. 自学机器学习、深度学习、人工智能学习资源推大聚合
  6. java socket 二次发送_发过2次帖子,都没有了,再发。JAVA中SOCKET通信中的数据压缩问题...
  7. 一些不错的C++网站[秋镇菜]
  8. xos详解5:PendSV_Handler
  9. 我的世界pe开服务器网站,我的世界pe服务器怎么开 开服图文教程
  10. 微软于 snapcraft 上发布 Visual Studio Code 的 Snap 打包版本
  11. 常用HTML登录页面模板
  12. 搭建一个 nodejs 脚手架
  13. 计算机重新启动操作处于挂起状态,PHOTOSHOPCS5安装程序检测到计算机重新启动操作可能处于挂起状态...
  14. ADC基本原理与STM32F030ADC应用
  15. 熵、图像熵的意义及计算方法
  16. linux查询主机信息命令,用来获取Linux主机信息的5个常用命令
  17. 计算机专业报考小学语文老师,各位大神,我是今年的专科应届毕业生,计算机应用专业,想当小学语文老师,考教师资格证对专业有限制吗?...
  18. Swi-Prolog借助XPCE可视化-显示图片
  19. 安卓实现消息提醒(震动和提示音)
  20. 基于SMTP协议的电子邮件客户端程序

热门文章

  1. 云计算的三种服务模式:IaaS、PaaS、SaaS
  2. 前端接收java后端返回base64二进制流下载mp4
  3. DOS命令diskpart格式化磁盘
  4. 投票问题 python
  5. Python实现分卷压缩
  6. HigherHRNet代码复现问题集(assert isinstance(orig, torch.nn.Module))
  7. 七牛云图片服务器搭建,对接
  8. 硬座、软座、硬卧、软卧、以及餐车座
  9. 在线FLV播放器实现方法
  10. 886. 可能的二分法