【JS】函数继承(重点)

继承

  • 继承是和构造函数相关的一个应用
  • 让一个构造函数去拥有另一个构造函数的属性和方法
  • 所以继承一定出现在两个构造函数之间

举个例子

  • 构造函数(类)是对一类行为的描述
  • 那么我们类这个概念其实也很抽象
  • 比如:
    • 我们说 国光 / 富士 都是 苹果的品种,那么我们就可以写一个 苹果类 来实例化很多品种出来
    • 苹果 / 梨 这些东西都是水果的一种,那么我们就可以写一个 水果类
    • 统一特点就是 甜 / 水分多,而不同的水果有不同的特征
    • 那么我们就可以让 苹果类 来继承 水果类 的内容,然后再用 水果类 去实例化对象
    • 那么实例化出来的就不光有 苹果类 的属性和方法,还有 水果类 的属性和方法

继承的作用

  • 在我们书写构造函数的时候,为了解决一个函数重复出现的问题
  • 我们把构造函数的 方法 写在了 prototype

在这里插入图片描述

  • 这样,每一个实例使用的方法就都是来自构造函数的 prototype
  • 就避免了函数重复出现占用内存得到情况
  • 但是两个构造函数的 prototype 中有一样的方法也是一种浪费
  • 所以我们把构造函数底 prototype 中的公共的方法再次进行提取
  • 我们准备一个更公共的构造函数,让构造函数的 _proto_ 指向这个公共的构造函数的 prototype

在这里插入图片描述

常见继承方式

原型继承

  • 就是在本身的原型链上加一层结构
function Father(){
	this.money = '100w';
}
var f = new Father();
console.log(f);

// 原型继承
function Son(){

}
// 使用构造函数将以前的原型换一个新的对象 - 完成了继承
Son.prototype = f;
// 给这个原型设置constructor
f.constructor = Son;
var s = new Son();
// s.__proto__ = f
console.log(s);
console.log(s.money);
// 当一个对象访问属性的时候,先在自己身上找属性,找不到,去原型上找,原型也没有,继续找原型的原型 .... null - undefined

在这里插入图片描述

  • 原型继承的缺陷:传参不好处理
function Father(height){
    this.money = '100w';
    this.height = height;
}

var f = new Father('180cm')

function Son(){
    // 子构造函数,希望能有父的height,但是希望值不一样
}
Son.prototype = f
var s = new Son()
console.log(s.height);	// 180cm
// 不同的子元素得到的height都是一样的
var s1 = new Son()
console.log(s1.height);	// 180cm

借用构造函数继承

  • 把父类构造函数体借用过来使用一下而已
// 借用函数/上下文调用模式
// call / apply / bind
function Father(){
    this.money = '100w';
}
function Son(){
    // 在子构造函数中,利用借用函数调用父构造函数
    // this代码s对象
    Father.call(this)
    // Father.call 是在调用Father这个函数,执行:
    /*
    this.money = '100w'
    将this换成s,相当于执行的是:s.money = '100w'
    */
}
var s = new Son()
console.log(s);
console.log(s.money);

在这里插入图片描述

  • 借用函数的缺陷:不能继承原型上的方法
function Father(){
	this.money = '100w';
}
Father.prototype.eat = function(){
	console.log("真能吃");
}
function Son(){
    Father.apply(this)
}

var s = new Son()
console.log(s.money);
console.log(s);
s.eat(); // 由于没有继承到父元素的该方法,所以直接报错

在这里插入图片描述

组合继承

  • 就是把 原型继承借用构造函数继承 两个方式组合在一起
  • 这样就能解决他们各自的缺陷,实现互补
// 混合继承:利用原型继承一次、利用借用函数继承一次,2合1
function Father(height){
    this.money = '100w'
    this.height = height
}
Father.prototype.eat = function(){
    console.log("能吃");
}
function Son(height){
    Father.apply(this,[height])
}

Son.prototype = new Father()


var s = new Son('170cm')
console.log(s);

在这里插入图片描述

ES6 的继承

  • 在es6之前,可以说没有类这个概念,es6中新增了定义类(构造函数的方式)
  • 语法:
class 子类 extends 父类{
	constructor(){
		super();
	}
}
  • 案例
class Father{
    constructor(height){
        this.money = '100w';
        this.height = height
    }
    eat(){
        console.log("能吃");
    }
}
// es6中的类的继承:
/*
class 子类 extends 父类{}
*/
class Son extends Father{
    constructor(height){
        // 子类如果有了constructor,首先必须先调用一个叫做super的方法
        super(height) // 相当于在调用父类的constructor
        // this.height = height
    }
}

var s = new Son('170cm')
console.log(s);
console.log(s.money);

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一颗不甘坠落的流星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值