1、原型链方式

  1. function Super(){
  2. this.val = 1;
  3. this.arr = [1];
  4. }
  5. function Sub(){
  6. // ...
  7. }
  8. Sub.prototype = new Super(); // 核心
  9.  
  10. var sub1 = new Sub();
  11. var sub2 = new Sub();
  12. sub1.val = 2;
  13. sub1.arr.push(2);
  14. alert(sub1.val); //
  15. alert(sub2.val); //
  16.  
  17. alert(sub1.arr); // 1, 2
  18. alert(sub2.arr); // 1, 2

拿父类实例来充当子类原型对象

优点:

  1. 简单,易于实现

缺点:

  1. 修改sub1.arr后sub2.arr也变了,因为来自原型对象的引用属性是所有实例共享的。

    可以这样理解:执行sub1.arr.push(2);先对sub1进行属性查找,找遍了实例属性(在本例中没有实例属性),没找到,就开始顺着原型链向上找,拿到了sub1的原型对象,一搜身,发现有arr属性。于是给arr末尾插入了2,所以sub2.arr也变了

  2. 创建子类实例时,无法向父类构造函数传参

2、借用构造函数方式

  1. function Super(val){
  2. this.val = val;
  3. this.arr = [1];
  4.  
  5. this.fun = function(){
  6. // ...
  7. }
  8. }
  9. function Sub(val){
  10. Super.call(this, val); // 核心
  11. // ...
  12. }
  13.  
  14. var sub1 = new Sub(1);
  15. var sub2 = new Sub(2);
  16. sub1.arr.push(2);
  17. alert(sub1.val); //
  18. alert(sub2.val); //
  19.  
  20. alert(sub1.arr); // 1, 2
  21. alert(sub2.arr); //
  22.  
  23. alert(sub1.fun === sub2.fun); // false

借父类的构造函数来增强子类实例,等于是把父类的实例属性复制了一份给子类实例装上了(完全没有用到原型)

优点:

  1. 解决了子类实例共享父类引用属性的问题

  2. 创建子类实例时,可以向父类构造函数传参

缺点:

  1. 无法实现函数复用,每个子类实例都持有一个新的fun函数,太多了就会影响性能,内存爆炸。。

3、组合继承方式

  1. function Super(){
  2. // 只在此处声明基本属性和引用属性
  3. this.val = 1;
  4. this.arr = [1];
  5. }
  6. // 在此处声明函数
  7. Super.prototype.fun1 = function(){};
  8. Super.prototype.fun2 = function(){};
  9. //Super.prototype.fun3...
  10. function Sub(){
  11. Super.call(this); // 核心
  12. // ...
  13. }
  14. Sub.prototype = new Super(); // 核心
  15.  
  16. var sub1 = new Sub(1);
  17. var sub2 = new Sub(2);
  18. alert(sub1.fun === sub2.fun); // true

把实例函数都放在原型对象上,以实现函数复用。同时还要保留借用构造函数方式的优点,通过Super.call(this);继承父类的基本属性和引用属性并保留能传参的优点;通过Sub.prototype = new Super();继承父类函数,实现函数复用

优点:

  1. 不存在引用属性共享问题
  2. 可传参
  3. 函数可复用

缺点:

  1. (一点小瑕疵)子类原型上有一份多余的父类实例属性,因为父类构造函数被调用了两次,生成了两份,而子类实例上的那一份屏蔽了子类原型上的。。。又是内存浪费,比刚才情况好点,不过确实是瑕疵

4、寄生组合继承方式

  1. function beget(obj){
  2. var F = function(){};
  3. F.prototype = obj;
  4. return new F();
  5. }
  6. function Super(){
  7. // 只在此处声明基本属性和引用属性
  8. this.val = 1;
  9. this.arr = [1];
  10. }
  11. // 在此处声明函数
  12. Super.prototype.fun1 = function(){};
  13. Super.prototype.fun2 = function(){};
  14. //Super.prototype.fun3...
  15. function Sub(){
  16. Super.call(this); // 核心
  17. // ...
  18. }
  19. var proto = beget(Super.prototype); // 核心
  20. proto.constructor = Sub; // 核心
  21. Sub.prototype = proto; // 核心
  22.  
  23. var sub = new Sub();
  24. alert(sub.val);
  25. alert(sub.arr);

转载:https://www.cnblogs.com/ayqy/p/4471638.html

js的几种继承方式的更多相关文章

  1. js的6种继承方式

    重新理解js的6种继承方式 注:本文引用于http://www.cnblogs.com/ayqy/p/4471638.html 重点看第三点 组合继承(最常用) 写在前面 一直不喜欢JS的OOP,在学 ...

  2. 细说 js 的7种继承方式

    在这之前,先搞清楚下面这个问题: function Father(){} Father.prototype.name = 'father'; Father.prototype.children = [ ...

  3. js的三种继承方式及其优缺点

    [转] 第一种,prototype的方式: //父类 function person(){ this.hair = 'black'; this.eye = 'black'; this.skin = ' ...

  4. 重新理解JS的6种继承方式

    写在前面 一直不喜欢JS的OOP,在学习阶段好像也用不到,总觉得JS的OOP不伦不类的,可能是因为先接触了Java,所以对JS的OO部分有些抵触. 偏见归偏见,既然面试官问到了JS的OOP,那么说明这 ...

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

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

  6. js的2种继承方式详解

    js中继承可以分为两种:对象冒充和原型链方式 一.对象冒充包括三种:临时属性方式.call()及apply()方式1.临时属性方式 复制代码代码如下: function Person(name){   ...

  7. JavaScript_几种继承方式(2017-07-04)

    原型链继承 核心: 将父类的实例作为子类的原型 //父类 function SuperType() {   this.property = true; } SuperType.prototype.ge ...

  8. js实现的几种继承方式

    他山之石,可以攻玉,本人一直以谦虚的态度学他人之所长,补自己之所短,望各位老师指正! 拜谢 js几种继承方式,学习中的总结: 所谓的继承是为了继承共有的属性,减少不必要代码的书写 第一种:借用构造函数 ...

  9. 都0202年了,你还不知道javascript有几种继承方式?

    前言     当面试官问你:你了解js哪些继承方式?es6的class继承是如何实现的?你心中有很清晰的答案吗?如果没有的话,可以通过阅读本文,帮助你更深刻地理解js的所有继承方式.       js ...

随机推荐

  1. Ifconfig- Linux必学的60个命令

    1.作用 ifconfig用于查看和更改网络接口的地址和参数,包括IP地址.网络掩码.广播地址,使用权限是超级用户. 2.格式 ifconfig -interface [options] addres ...

  2. python3 使用aria2下载的一个脚本

    import requests import time ariaurl="http://localhost:6800/jsonrpc" dlurl="http://xxx ...

  3. [JZOJ4648] 【NOIP2016提高A组模拟7.17】锦标赛

    题目 描述 题目大意 有nnn个人,你要确定一个出场序列.每次新上台的人就会和擂主打一架,胜利的人继续当擂主.题目给出两两之间打架胜利(失败)的概率. 问111选手坚持到最后的最大概率. 思考历程 看 ...

  4. 第一个duilib程序 - 实现HelloWorld详解

    duilib是一个windows下的皮肤库,用win32写的... 先看个效果图吧: 要使用duilib库,必须先把库导入,代码如下: View Row Code 1 #include "x ...

  5. 单独安装Babel或者Less

    1.直接安装Babel法: 1)初始化自动创建package.json npm init 2)首先全局安装Babel. npm install -g babel-cli 3)项目安装Babel. np ...

  6. 《DSP using MATLAB》Problem 8.14

    代码: %% ------------------------------------------------------------------------ %% Output Info about ...

  7. jquery刷新局部和全页的方法

    一.全页面刷新方法: window.location.reload()刷新当前页面. parent.location.reload()刷新父亲对象(用于框架) opener.location.relo ...

  8. walle(瓦力)部署系统的安装和简单使用

    Walle(瓦力):一套软件开发的部署系统.提供了清晰的日志记录,支持数据的回滚.用于解决大型团队在软件开发中的测试.预测试和上线的统一部署管理. 系统环境:CentOS6.8-A CentOS-6. ...

  9. hdu1527

    hdu1527两堆博弈模型,威佐夫博弈 #include<iostream> #include<cstdio> #include<queue> #include&l ...

  10. 大数据处理也要安全--关于MaxCompute的安全科普

    [TOC] 1.企业大数据处理现状 当今社会数据收集手段不断丰富,行业数据大量积累,数据规模已增长到了传统软件行业无法承载的海量数据(百GB.TB乃至PB)级别.基于此,阿里云推出有了一套快速.完全托 ...