一文详解JavaScript的继承模式
1 原型链继承
#### ES6中通过原型继承多个引用类型的属性和方法,由于原型和实例的关系,即每个构造函数都有自己的原型对象,同时原型有一个属性指向构造函数,并且实例有一个内部的指针指向原型。如果存在某原型是另一个类型的实例时,以此类推。便形成了原型链。
-实现原型链的基本代码模式:
function SubType(){}
SubType.prototype.getValue = function(){}
此时,函数SubType的原型上边定义了一个方法 getValue 在下一步进行实例化的时候,便可以通过这个方法访问函数上的相关属性。
同时,一个函数或者方法的原型可以继承自另外一个函数或者类的实例。
例如:
function SonType(){}
继承自SubType
SonType.prototype = new SubType();
读取实例上的属性的原则:首先会在实例上搜索这个属性,如果未找到,则会搜索继承实例的原型,以此向上,搜索原型的原型。一直持续到原型链的末端。
2 盗用构造函数实现继承
改继承方式可以解决原型包含引用值导致的继承问题,(即可能会导致实现多个不必要的引用或者方法)。
例:
function SuperType(){
this.color = ['red','blue','green']
}
继承自SuperType
function SubType(){ SuperType.call(this) }
let instance = new SubType();
instance.color.push("skyblue)
console.log(instance.color)
red,blue,green,skyblue
;
上述代码展示了盗用构造函数的调用,通过使用call或者apply方法SuperType构造函数能够在实例化SubType的实例时,在其新对象的上下文中执行。
此种方式的优点在于能够在子类的构造函数当中向父类的构造函数传递参数。
SuperType.call(this,'此处传递参数')
缺点在于必须在构造函数中定义方法,函数无法重用,同时子类也无法访问父类原型上的定义的方法。
组合式继承模式
该继承综合了原型链和盗用构造函数继承:将优点集中到一起。
基本思路:通过原型链继承原型上的属性和方法,通过盗用构造函数继承实例属性。
实例代码:
function SuperType(){
this.name = name;
this.colors = ['red','blue','green']
}
SuperType.prototype.sayName = function(){
console.log(this.name)
}
function SubType(name,age){
SuperType.call(this,name);
this.age = age;
}
SubType.ptototype = new SuperType();
SubType.prototype.sayAge = function(){
console.log(this.age)
}
该继承模式弥补了原型链继承和盗用构造函数继承的不足,是使用最多的继承模式,同时还保留了instanceof操作符和isPrototypeOf()方法。
原型式继承
function object(o) {
function F(){};
F.prototype = o;
return new F();
}
object函数会临时创建一个构造函数,将传入的对象赋值个这个构造函数的原型,最后返回这个临时类型的一个实例,本质上,相当于一次浅复制。
ES6中通过增加Object.create()方法实现原型式继承。该方法接收两个参数,1 作为新对象原型的对象。2 给新对象定义额外属性的对象。(可选)
当只有一个参数时,同上文定义的object函数功能相同。
寄生式继承
function createAnother(origin){
let clone = object(origin); 通过调用构造函数创建一个新对象 object函数和原型式继承类似
clone.sayname = function(){ 增强这个新对象的属性和方法
console.log("say hi")
}
return clone;
}
思路类似于:寄生构造函数和工厂模式。创建一个实现继承的函数,以某种方式增强这个对象,最后返回。
寄生式组合继承
组合继承示例:
function SuperType(name){
this.name = name;
this.colors = ['red','blue','green'];
}
SuperType.prototype.sayName = function(){
console.log(this.name);
}
function SubType(name,age){
SuperType.call(this,name); 第二次调用SuperType
this.age = age;
}
SubType.prototype = new SuperType();
第一次调用SuperType()
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
console.log(this.age);
}
寄生式组合继承
function inheritPrototype(subType,superType){
let prototype = object(superType.prototype); 创建对象
prototype.constructor = subType(); 增强对象
subType.prototype = prototype; 赋值对象
}
通过这种方式 只需要调用一次SuperType构造函数效率更高,原型键依然保持不变,同时instance操作符和isProtoTpe方法正常有效。
一文详解JavaScript的继承模式的更多相关文章
- 详解Javascript的继承实现(二)
上文<详解Javascript的继承实现>介绍了一个通用的继承库,基于该库,可以快速构建带继承关系和静态成员的javascript类,好使用也好理解,额外的好处是,如果所有类都用这种库来构 ...
- 详解Javascript的继承实现
我最早掌握的在js中实现继承的方法是在w3school学到的混合原型链和对象冒充的方法,在工作中,只要用到继承的时候,我都是用这个方法实现.它的实现简单,思路清晰:用对象冒充继承父类构造函数的属性,用 ...
- 详解JavaScript对象继承方式
一.对象冒充 其原理如下:构造函数使用 this 关键字给所有属性和方法赋值(即采用类声明的构造函数方式).因为构造函数只是一个函数,所以可使 Parent 构造函数成为 Children 的方法,然 ...
- 【转】详解JavaScript中的this
ref:http://blog.jobbole.com/39305/ 来源:foocoder 详解JavaScript中的this JavaScript中的this总是让人迷惑,应该是js众所周知的坑 ...
- js对象详解(JavaScript对象深度剖析,深度理解js对象)
js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...
- (转载)详解Javascript中prototype属性(推荐)
在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不存在类(Class)的概念的,javascript中不 ...
- 详解javascript的类
前言 生活有度,人生添寿. 原文地址:详解javascript的类 博主博客地址:Damonare的个人博客 Javascript从当初的一个"弹窗语言",一步步发展成为现在前后端 ...
- 一文详解Hexo+Github小白建站
作者:玩世不恭的Coder时间:2020-03-08说明:本文为原创文章,未经允许不可转载,转载前请联系作者 一文详解Hexo+Github小白建站 前言 GitHub是一个面向开源及私有软件项目的托 ...
- 转:Windows下的PHP开发环境搭建——PHP线程安全与非线程安全、Apache版本选择,及详解五种运行模式。
原文来自于:http://www.ituring.com.cn/article/128439 Windows下的PHP开发环境搭建——PHP线程安全与非线程安全.Apache版本选择,及详解五种运行模 ...
随机推荐
- Azure 实践(1)- Azure Devops Server 安装
1.Azure Devops介绍 Azure DevOps Server 2020 (之前的名称为TFS),作为微软Azure DevOps 的企业私有(on-premises)服务器,是一个为开发团 ...
- Docker部署ELK之部署kibana7.6.0(2)
1. 拉取kibana镜像 sudo docker pull kibana:7.6.0 2. 输入命令构建kibana容器,关于挂载kibana配置文件的问题,也可以先构建一个容器,然后把配置文件co ...
- 以命令行方式使用Desktop版Ubuntu
方法1:安装Ubuntu Server版,好处是默认不安装GUI,且可以自动安装ssh服务和其他很多服务,且消耗系统资源少(约200MB内存,Desktop版启动后需要500MB左右内存),启动和关闭 ...
- Nginx中location匹配及rewrite重写
目录 一.常用的Nginx正则表达式 二.location 2.1.location三类匹配类型 2.2.常用的匹配规则 2.3.location优先级 2.3.1.举例说明 2.4.实际网站使用中, ...
- k8s 执行 ingress yaml 文件报错: error when creating "ingress-myapp.yaml": Internal error occurred: failed calling webhook
k8s 执行 ingress yaml 文件报错:错误如下: [root@k8s-master01 baremetal]# kubectl apply -f ingress-test.yaml Err ...
- Asp.NetCore 中Aop的应用
前言 其实好多项目中,做一些数据拦截.数据缓存都有Aop的概念,只是实现方式不一样:之前大家可能都会利用过滤器来实现Aop的功能,如果是Asp.NetCore的话,也可能会使用中间件: 而这种实现方式 ...
- asp.net MVC 的路由匹配
- asp.net core 声明controller的方法
1, 对类名直接添加Controller, 如TestController. 2, 继承Controller 类. 3, 对类名添加controller的属性, 如[Controller]
- 13.SpringMVC之全局异常
我们知道,系统中异常包括:编译时异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发.测试通过手段减少运行时异常的发生.在开发中,不管是dao层 ...
- dubbo(一)
1. Introduction 参考链接:https://www.baeldung.com/dubbo Dubbo is an open-source RPC and microservice fra ...