博客
关于我
JS中的常用继承方式总结
阅读量:268 次
发布时间:2019-03-01

本文共 3264 字,大约阅读时间需要 10 分钟。

JS中的多种继承方式

JS本身是基于面向对象开发的编程语言,所以学习JS的时候基本上就是学习它有哪些类,学习这些类的实例,实例可以调用类原型提供的方法,实例还有自己私有的属性和方法。
面向对象想编程中有一个非常重要的知识点 -- 类:封装、继承、多态

  • 封装 :类也是一个函数,把实现一个功能的代码进行封装,以此实现“低耦合高内聚”
  • 多态:重载、重写
    • 重写:子类重写父类上的方法(把随着继承运行的)
    • 重载: 相同的方法,由于参数或者返回值不同,具备了不同的功能(JS不具备严格意义下的重载的),JS中的重载指同一个方法,根据传参的不同,依次判断处理,实现不同的功能。
  • 继承 = > 继承的目的:让子类的实例同时具备父类中的私有属性和公共方法

JS中的继承方法一 :原型继承

原型继承:让子类的原型等于父类的实例 => Child.prototype = new Parent;(实现继承)

特点:

  1. 父类中私有的和公有的属性和方法,最后都变为子类实例的公有的属性和方法
  2. 和其他语言不同的是,原型继承并不会把父类的属性和方法“拷贝”给子类,而是让子类实例基于__proto__(原型链)找到自己定义的属性和方法–“指向/查找”方式的。
  • c1.__proto__.xxx = xxx;修改子类原型(原有父类的实例)中的内容,内容被修改后,对子类的其他实例有影响,对父类的其他实例没有影响想
  • c1.__proto__.__proto__.xxx = xxx;直接修改的是父类的原型,这样不仅会影响其他子类的实例,也会影响其他父类的实例。

EG:

function Parent(){   	this.x = 100;};Parent.prototype.getX = function getX(){   	return this.x;};function Child(){   	this.y = 200;};Child.prototype = new Parent;//实现继承Child.prototype.constructor = Child//为了保证Child原型的完整性,手动添加上constructor Child.prototype.getY = function getY(){   	return this.y;};let c1 = new Child;

图例解析

在这里插入图片描述

  1. 缺点:
    1. 原型继承并不会把父类的属性和方法“拷贝”给子类,而是让子类实例基于__proto__(原型链)找到自己定义的属性和方法
    2. 会把父类公有的和私有的属性和方法,全部变成了子类实例公有的属性和方法
  2. 期望:
    1. 让父类私有的变成子类实例私有的
    2. 让父类公有的变成子类实例公有的

JS中的继承方法二 :call继承

  • 在子类的构函数中把父类当做普通方法执行(没有父类实例,父类原型上的那些东西也就和子类没有关系了)
  • Parent.call(this)中的this.x = 100,相当于给实例c1设置一个私有的属性x,属性值是100,相当于让子类的实例继承了父类的私有属性,并且变为了子类的私有属性,这就是"拷贝式"。
  • 特点:只能继承父类私有的,不能继承继承父类公有的
function Parent(){   	this.x = 100;};Parent.prototype.getX = function getX(){   	return this.x;};function Child(){   	Parent.call(this);	this.y = 200;};Child.prototype.getY = function getY(){   	return this.y;};let c1 = new Child;

缺点:

  • 只能继承父类中私有的
  • 不能继承父类中公有的

JS中的继承方法三:寄生组合式继承

  • 理想的继承方式:父类私有的变为子类私有的,父类公有的变为子类公有的
  • 寄生组合式继承:CAll继承+另类原型继承
    • 核心点Child.prototype.__proto__ === Parent.prototype
    • 通过call继承可以把父类私有的变为子类私有,但是无法继承父类公有的
    • 通过把子类的原型链指向父类的原型,可以继承父类的公有办法,但是IE浏览器不支持修改__proto__, 所以利用:Child.prototype= Object.create(Parent.prototype)
    • 为了保证Child原型的完整性,手动加上Child.prototype.constructor = Child

EG:

function Parent(){   	this.x = 100;};Parent.prototype.getX = function getX(){   	return this.x;};function Child(){   	Parent.call(this);//继承父类的私有属性方法	this.y = 200;};//Child.prototype.__proto__ === Parent.prototype //IE浏览器不支持Child.prototype= Object.create(Parent.prototype);//继承父类的公有属性方法Child.prototype.constructor = Child;// 为了保证Child原型的完整性Child.prototype.getY = function getY(){   	return this.y;};let c1 = new Child;

图形解释:Child.prototype.__proto__ === Parent.prototype【IE浏览器不支持】在这里插入图片描述

图形解释:Child.prototype= Object.create(Parent.prototype)
在这里插入图片描述

知识扩展:Object.create(obj)

  • 创建一个空对象,让其原型链指向obj;obj为一个类的原型。
  • Object.create(Parent.prototype):创建一个空对象,让其原型链指向Parent的原型[prototype]

ES6中类的继承(extends Parent)

  • ES6中创建的类就是类,不能被当做普通函数执行,只能new执行
    • 不加new自执行函数会报错:“Uncaught TypeError: Class constructor Child cannot be invoked without ‘new’”
  • 继承: 子类 extends 父类 (类似于寄生组合是继承)
  • 继承后子类constructor第一行必须加上super(),类似于之前的call继承,super(100,200):
    • 相当于把Parent中的constructor执行,传递了100和200
    • 不加报错:‘Must call super constructor in derived class before accessing ‘this’ or returning from derived constructor’
//ES6中类和继承class Parent{   	constructor (){   		this.x = 100;	};	//等价于:Parent.prototype.getX = function...	getX(){   		return this.x;	}};class Child  extends Parent{   	constructor (){   		super();//继承后子类constructor第一行必须加上super(),否则会报错。    at new Child 		this.y = 200;	};	getY(){   		return this.y;	}};new Child();

转载地址:http://bmho.baihongyu.com/

你可能感兴趣的文章
Rhapsody的文件能转到EA里面吗
查看>>
一张图让你了解——mysql高可用:分库分表
查看>>
《程序猿的第n+3天》bootstrap做收缩导航
查看>>
android instant app
查看>>
ubuntu非root用户如何访问vmware共享文件夹
查看>>
如何使用Postman保存请求和返回,离线查看请求数据
查看>>
系统架构
查看>>
图解HTTP (chap4 Http状态码) 5XX
查看>>
creator世界坐标w_pos会变化导致的录屏回放时相对位置变化造成bug(改为local_pos即可解决)
查看>>
Python3实现程序更新
查看>>
类似愤怒小鸟的飞行弹道
查看>>
(二十七)unity4.6学习Ugui中文文档-------Unity3D UI (uGUI)窗口扩展
查看>>
Android官方文档之DataBinding库
查看>>
【python】输出到文件, f.write与print
查看>>
【今日CV 计算机视觉论文速览 第97期】Tue, 9 Apr 2019
查看>>
【mAP】关于目标检测mAP的一些理解
查看>>
庄子:谁知南华秋水意?
查看>>
android 在一个应用中启动另一个应用
查看>>
Thread.sleep() 和 Thread.yield() 区别
查看>>
Kotlin 简单优雅的高阶函数
查看>>