详细理解JS中的继承
- JS只支持实现继承,即继承实际的方法,不支持接口继承(即继承方法的签名,但JS中函数没签名)
- 所有对象都继承了Object.prototype上的属性和方法。
- 说继承之前还要再说一下原型。原型之所以很重要,原因之一就是可以利用它来实现JavaScript的继承。重写一个函数的原型对象,将其指定为另一个函数的实例,这样便实现了一个简单的原型链继承。
function Super(){
this.name='super';
}
Super.prototype.getName=function(){
console.log(this.name);
}
function Sub(){
this.name='sub';
} Sub.prototype=new Super();//重写原型,实现继承
var instance=new Sub();
instance.getName();//sub继承了getName方法
重写原型会让Sub的原型获得Super构造函数上和Super原型上的所有属性和方法; 但是这样单纯使用原型来继承也有问题,比如将上面的代码修改一下,在原型上添加一个引用类型的属性:
function Super() {
this.name='super';
}
Super.prototype.getName=function() {
console.log(this.name);
};
Super.prototype.color = ["red", "black"]; function Sub() {
} Sub.prototype=new Super();//实现继承 var instance=new Sub();
instance.color.push('white');//改变instance的color属性,push一个新的项
var ins = new Sub();
console.log(ins.color); //["red", "black", "white"] 可以看到ins的color属性也被改变了
- ① 借用构造函数(又叫经典继承,伪造对象)
function Arr(){
}
Arr.prototype.array=['red','black'];
arr01=new Arr();
arr02=new Arr();
arr01.array.push('white');
console.log(arr02.array);//["red", "black", "white"]
function superType(){
this.color=['red','blue','yellow'];
}
function subType(){
//继承了superType
superType.call(this);
} var instance01=new subType();
instance01.color.push('black');
console.log(instance01.color);//['red','blue','yellow','black'] var instance02=new subType();
console.log(instance02.color);//['red','blue','yellow']
借用构造函数这种方法主要就是:利用parent . call(this)来继承父级构造函数上公有的属性,且在一个实例上进行修改不会对其他实例造成影响;[ 注意:使用call这种不能继承原型上属性和方法的哦 ]
- ② 下面来说JS中最常用的继承模式:组合继承
function superType(name){
this.name=name;
this.color=['red','blue','yellow'];
}
superType.prototype.sayName=function(){
console.log(this.name);
} function subType(name,age){
//继承superType的属性
superType.call(this,name);
this.age=age;
}
//继承superType的方法
subType.prototype=new superType();
subType.prototype.constructor=subType;
subType.prototype.sayAge=function(){
console.log(this.age);
}; var instance01=new subType('lazy',20);
instance01.color.push('black');
console.log(instance01.color);//['red','blue','yellow','black']
instance01.sayAge();//
instance01.sayName();//lazy var instance02=new subType('chen',21);
console.log(instance02.color);//['red','blue','yellow']
instance02.sayAge();//
instance02.sayName();//chen
superType.call(this,name);
- ③ 寄生组合式继承
function superType(name){
this.name=name;
this.color=['red','blue','yellow'];
}
superType.prototype.sayName=function(){
console.log(this.name);
} function subType(name,age){
//继承superType
superType.call(this,name);
this.age=age;
} function inheritPrototype(sub,sup){
//创建超类型构造函数的原型副本
var prototype=Object(sup.prototype);
//为其指定构造函数,增强对象
prototype.constructor=sub;
//重写sub的原型对象
sub.prototype=prototype;
} //copy一份超类型构造函数的原型对象给子类型构造函数
inheritPrototype(subType,superType); subType.prototype.sayAge=function(){
console.log(this.age);
}; var instance01=new subType('lazy',20);
instance01.color.push('black');
console.log(instance01.color);//['red','blue','yellow','black']
instance01.sayAge();//
instance01.sayName();//lazy var instance02=new subType('chen',21);
console.log(instance02.color);//['red','blue','yellow']
instance02.sayAge();//
instance02.sayName();//chen
这种方法主要依然是利用 借用构造函数的方法来继承构造函数的属性,利用原型链的混合方法来继承方法;基本思路是:不必为了重写subType的原型而去调用一次superType,因为我们需要的也只是superType的原型对象的一个副本而已,所以有了inheritPrototype函数:
function inheritPrototype ( sub ,super) {
var prototype = Object( super.prototype ); //创建副本
sub.prototype = prototype ;
prototype . constructor = sub ;
}
- ④寄生式继承 :在主要考虑对象而不是自定义类型和构造函数的情况下,寄生式继承也是一种很有用的模式,看个例子:
function createAnother(original) {
var clone = Object(original);
clone.sayHi = function () {
console.log('hi');
};
return clone;
} var person = {
name: 'lazy',
friends:[1,2,3]
}; var anotherPerson = createAnother(person);
anotherPerson.sayHi();
console.log(anotherPerson.name);
这个例子中,基于person对象创建了一个新的对象anotherPerson,这个新的对象不仅具有person的所有属性和方法,而且还有自己的sayHi方法;
菜鸟小白一枚,可能上述有错误或理解不对的地方,恳请指出~~谢谢!
详细理解JS中的继承的更多相关文章
- 【学习笔记】六:面向对象的程序设计——理解JS中的对象属性、创建对象、JS中的继承
ES中没有类的概念,这也使其对象和其他语言中的对象有所不同,ES中定义对象为:“无序属性的集合,其属性包含基本值.对象或者函数”.现在常用的创建单个对象的方法为对象字面量形式.在常见多个对象时,使用工 ...
- 怎么理解js中的事件委托
怎么理解js中的事件委托 时间 2015-01-15 00:59:59 SegmentFault 原文 http://segmentfault.com/blog/sunchengli/119000 ...
- JS中的继承(上)
JS中的继承(上) 学过java或者c#之类语言的同学,应该会对js的继承感到很困惑--不要问我怎么知道的,js的继承主要是基于原型(prototype)的,对js的原型感兴趣的同学,可以了解一下我之 ...
- 图文结合深入理解 JS 中的 this 值
图文结合深入理解 JS 中的 this 值 在 JS 中最常见的莫过于函数了,在函数(方法)中 this 的出现频率特别高,那么 this 到底是什么呢,今天就和大家一起学习总结一下 JS 中的 th ...
- 深入理解JS中的对象(三):class 的工作原理
目录 序言 class 是一个特殊的函数 class 的工作原理 class 继承的原型链关系 参考 1.序言 ECMAScript 2015(ES6) 中引入的 JavaScript 类实质上是 J ...
- 深入理解Js中的this
深入理解Js中的this JavaScript作用域为静态作用域static scope,但是在Js中的this却是一个例外,this的指向问题就类似于动态作用域,其并不关心函数和作用域是如何声明以及 ...
- js中实现继承的几种方式
首先我们了解,js中的继承是主要是由原型链实现的.那么什么是原型链呢? 由于每个实例中都有一个指向原型对象的指针,如果一个对象的原型对象,是另一个构造函数的实例,这个对象的原型对象就会指向另一个对象的 ...
- 如何更好的理解js中的this,分享2段有意思的代码
关于js中this的浅析,大家可以点击[彻底理解js中this的指向,不必硬背]这篇博客了解. 今天遇到2段比较有意思的代码. ----------------第一段----------------- ...
- JS中的继承(下)
JS中的继承(下) 在上一篇 JS中的继承(上) 我们介绍了3种比较常用的js继承方法,如果你没看过,那么建议你先看一下,因为接下来要写的内容, 是建立在此基础上的.另外本文作为我个人的读书笔记,才疏 ...
随机推荐
- WPF资源字典的使用
1.在解决方案中添加资源字典:鼠标右键——添加——资源字典 2.在资源字典中写入你需要的样式,我这里简单的写了一个窗体的边框样式 3.在App.xaml中加入刚刚新建的资源字典就好了
- docker--docker架构
4 docker 架构 Docker uses a client-server architecture. The Docker client talks to the Docker daemon, ...
- Nacos 配置中心原理分析
我们从原生SDK代码中入手,可以发现最核心的两行代码: ConfigService configService=); 首先我们先来看 NacosFactory.createConfigService ...
- 洛谷 P1462 通往奥格瑞玛的道路(二分答案,堆优化dijkstra)
传送门 解题思路 首先看题目问题,求经过的所有城市中最多的一次收取的费用的最小值是多少.一看“最大值最小”就想到了二分答案. 在读一遍题目,就是二分收取的费用,然后对于每一个二分的费用,跑一边最短路, ...
- struts2 spring 优缺点
struts框架具有组件的模块化,灵活性和重用性的优点,同时简化了基于MVC的web应用程序的开发.优点:Struts跟Tomcat.Turbine等诸多Apache项目一样,是开源软件,这是它的一大 ...
- k3 cloud工程量清单调整后工程量为零行设置为黄色
#引入clr运行库 import clr #添加对cloud插件开发的常用组件的引用 clr.AddReference('Kingdee.BOS') clr.AddReference('Kingdee ...
- Unity 官网无法访问|国外网站访问过慢|国外网站访问加速器
目录 1. 文档地址 2. 按 3. 工具下载地址 1. 文档地址 GitHub博客 https://coco5666.github.io/blog/articles/20190704-01/ 2. ...
- 线程池-连接池-JDBC实例-JDBC连接池技术
线程池和连接池 线程池的原理: 来看一下线程池究竟是怎么一回事?其实线程池的原理很简单,类似于操作系统中的缓冲区的概念,它的流程如下:先启动若干数量的线程,并让这些线程都处于睡眠状态,当客 ...
- BZOJ3129/洛谷P3301方程(SDOI2013)容斥原理+扩展Lucas定理
题意:给定方程x1+x2+....xn=m,每个x是正整数.但是对前n1个数做了限制x1<=a1,x2<=a2...xn1<=an1,同时对第n1+1到n1+n2个数也做了限制xn1 ...
- mysql 通过navicat 添加函数或者过程
1. 添加函数时, 函数参数的 varchar(255) 一定要加上 255,返回也要加.不加一直保存不了,狂试: 2. 添加过程时, 进入课程体 编辑时 也要加上 varchar 的位数限制.不 ...