js实现继承的方法
父类
function Animal(name){ this.name=name } Animal.prototype.eat=function(food){ console.log(this.name+'吃'+food) }
原型链继承
function Cat(){}
Cat.prototype=new Animal()
var cat=new Cat()
console.log(cat.name)
console.log(cat.eat('鱼'))
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //true
特点:
1,经典的继承关系,实例是子类的实例也是父类的实例
console.log(cat instanceof Animal); //true console.log(cat instanceof Cat); //true
2,父类新增的原型属性,子类也能访问(原型链)
缺点:
1,由于prototype被new Animal('cat')占据,所以子类想要拓展新属性或者方法必须在new Animal('cat')之后,灵活度受限
2,只能继承一个
3,由于继承自父类的实例对象,子类已经没办法通过参数修改子类实例的属性,比如我想创建name为小白的实例,但是修改的方法在父类那里,子类无法在创建时赋予name属性,
4,会将父级实例对象的属性继承至原型,导致所有实例共享,比如上述的子类就继承了父类实例的name=undefinde
构造继承
function Cat(name){ Animal.apply(this,arguments) } var cat = new Cat('Tom'); console.log(cat.name); console.log(cat.eat('鱼'))//报错 console.log(cat instanceof Animal); // false console.log(cat instanceof Cat); // true
特点:
1,能够多继承(使用多个call或者apply)
2,能够传递参数进属于父类的函数
缺点:
1,实例是子类的实例,不是父类的实例
2,只能继承父类的实例属性和方法,不能继承父类的原型属性方法
3,也由于如此,这种继承方法只能将父类的实例函数继承为子类的实例函数,没办法继承原型上的方法,没办法复用函数
4,每个子类都有父类实例函数的副本,影响性能
实例继承
function Cat(){ var instance=new Animal() instance.name=name||'Tom' return instance } // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); // false
特点
1,不限制调用方法,无论是直接调用还是new都能拿到实例对象
缺点
1,实例是父类的实例,跟子类没关系,所以子类也没办法拓展原型
2,不支持多继承
拷贝继承
function Cat(name){ var animal=new Animal() for(let key in animal){ Cat.prototype[key]=animal[key] } this.name=name } let cat=new Cat() console.log(cat.name) console.log(cat.eat()) console.log(cat instanceof Animal) console.log(cat instanceof Cat)
特点
1,支持多继承
缺点
1,效率低,内存占用高,每个子类都需要实例化父类,并且循环拷贝
2,无法获取父类不可枚举的属性,其中包含父类的原型
组合继承
function Cat(name){ Animal.apply(this,arguments); this.name = name || 'Tom'; } Cat.prototype=new Animal() Cat.prototype.constructor=Cat var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); // true
特点
1,这是构造继承+原型链继承的组合,弥补了构造继承的缺点无法继承父类的原型
2,实例既是父类的实例也是子类的实例
3,可以传参
4,继承自父类的原型可复用
缺点
1,调用了两次父类,消耗内存
寄生组合继承
function Cat(name){ Animal.apply(this,arguments) } (function(){ var Super=function(){} Super.prototype=Animal.prototype Cat.prototype = new Super(); })() var cat = new Cat(); console.log(cat.name); console.log(cat.eat()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); //true
特点
各方面都较为完善,可以继承自父类的构造属性和函数与父类的原型属性和函数,且避免了共享父级构造属性函数的情况(使用的super是一个空的构造函数),同时子类的参数也能参与父类的函数,并且子类实例也是父类的实例
缺点:
1,实现复杂,需要每个子类需要执行一次父类,一次匿名函数
问题,为何在实现继承时,不能让子类的原型对接父类的原型
问这个问题前首先要明白继承后我们想拿到什么结果
1,子类获取父类的所有属性与方法包括原型上的
2,子类与父类要形成继承关系,即子类的实例也是父类的实例,实例能通过原型链追寻到父类
然后在想直接使用父类的原型有什么后果
1,首先一点原型也是对象的属性,它是引用类型,所以子类与父类的prototype直接对接上会导致子类没办法修改原型参数,因为一旦修改了也是修改了父类的原型,由此也引发另外一个问题,子类失去了对应它构造函数的constructor,因为在这一通操作里,这一个是属于父类的,也就是指向父类的构造函数
原文地址:https://www.cnblogs.com/zsckl/p/15166376.html
- JavaWeb10-reques;response你不得不学(2)
- 很多人比较纠结的约束和索引的关系(r7笔记第75天)
- JavaWeb09-Servlet(Java真正的全栈开发)
- JavaWeb08-XML,tomcat,HTTP轻松入门
- JavaWeb07-JDBC(Java真正的全栈开发)
- 编程思想 之「操作符」
- Hyperledger fabric Chaincode 开发详解
- 字节码文件的内部结构之谜
- 基因功能富集分析-R语言
- CRM, C4C和Hybris的工作流简介
- 想进大厂?50个多线程面试题,你会多少?(一)
- golang 几种字符串的连接方式
- Go Template学习笔记
- Go语言实现控制台贪吃蛇
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 专属于六倍体小麦的Bioconductor注释包
- 轻松上传超过100M的文件至GitHub
- 转录组分析 | 使用DESeq2进行基因差异表达分析
- 生信基础 | 使用BLAST进行序列比对
- 批量提取基因上下游指定范围内的SNP标记
- 一文掌握Plink文件格式转换
- R语言绘图 | 绘制QQ图和曼哈顿图
- GWAS | 使用GEMMA进行全基因组关联分析
- 使用eggnog-mapper进行功能注释
- 离线环境下使用Conda安装软件
- 利用cutree划分pheatmap聚类结果
- 使用Mfuzz进行转录组表达模式聚类分析
- 使用PopLDdecay快速进行连锁不平衡分析
- 报错坑 | LDSC安装报错怎么解决?
- 看看斯坦福大学是如何教学生编程的