JavaScript面向对象之继承 (上)

版权声明:刘家军 https://blog.csdn.net/qq_42911663/article/details/85499571

原型链继承

我们再通过前几篇的例子再了解下原型链继承

//创建自定义构造函数
function Person() {
    this.name = "姓名";
}
//在当前构造函数的原型链上添加属性hobby
Person.prototype.hobby = "旅游"

//通过自定义构造函数Person实例化一个对象LJJ
const LJJ = new Person()
console.log(LJJ.hobby) // 旅游
//通过自定义构造函数Person实例化一个对象YH
const YH = new Person()
console.log(YH.hobby) // 旅游

从例字中 我们看到,LJJ与YH都从Person那里继承到了hobby “旅游”, 那我们继续往下看

//创建自定义构造函数
function Person() {
    this.name = "姓名";
}
//在当前构造函数的原型链上添加属性hobby
Person.prototype.hobby = "旅游"

//通过自定义构造函数Person实例化一个对象LJJ
const LJJ = new Person()
LJJ.hobby = "敲代码"
console.log(LJJ.hobby) // 敲代码
//通过自定义构造函数Person实例化一个对象YH
const YH = new Person()
console.log(YH.hobby) // 旅游

对LJJ的hobby重新赋值并没有影响YH的hobby,然后我们打印下LJJ;
输出:
在这里插入图片描述
LJJ的hobby屏蔽了原型链上的hobby,所以LJJ的hobby是"敲代码",而YH的hobby仍然是原型上的hobby"旅游"
我们再换一种写法,看代码:

function Person() {
    this.name = "姓名"
}
Person.prototype.hobby = ["旅游","看电影"]

const LJJ = new Person()
LJJ.hobby.push("敲代码") 
console.log(LJJ.hobby) // ["旅游", "看电影","敲代码"]
const YH = new Person()
//构造函数中的hobby已经被改变
console.log(YH.hobby) // ["旅游", "看电影","敲代码"]

因为在实例LJJ中添加引用类型导致改变了构造函数Person的hobby属性,因为LJJ与YH是Person的实例,都继承了Person的属性,所以Person的属性改变直接影响了他的实例;因此引入引用类型时应注意,我前面有一篇讲到了处理方法,但今天我们用另一种来解决

借用构造函数

借用?就是使用call或者apply改变一下this指向,
就是子类的构造函数内部通过call或者apply调用父类的构造函数,如果对call方法有不了解的地方,可以翻看昨天的文章

//创建一个构造函数,并添加一些属性
function Person() {
    this.name = "姓名"
    this.nickName = "昵称"
    this.hobby = ["爱好"]
}
//创建一个构造函数,并借用了Person的构造函数
function Ljj() {
        Person.call(this)
        this.name = "刘家军"
        this.hobby = ["旅游","敲代码"]
}
//创建一个构造函数,并借用了Person的构造函数
function Yh() {
    Person.call(this)
    this.name = "袁姮"
    this.hobby = ["旅游","看电影"]

}
const LJJ= new Ljj();
console.log(LJJ);

const YH = new Yh();
console.log(YH);

输出:
在这里插入图片描述
这样就避免了原型链继承中,构造函数中的属性或者方法被其他实例所改变的问题
但要注意一下代码执行顺序,不要被后面的代码覆盖了前面的代码,一般情况我们用到call()方法直接写在函数的第一行

借用构造函数进行传参

function Person(name,hobby) {
  this.name = name;
  this.hobby = hobby
}
function Ljj() {
  Person.call(this,"刘家军",["旅游","敲代码"])
}

function Yh() {
  Person.call(this,"袁姮",["旅游","看电影"])
}
const LJJ = new Ljj();
console.log(LJJ);

const YH = new Yh();
console.log(YH);

输出:
在这里插入图片描述

组合继承

将原型链和借用构造函数技术组合到一起。
使用原型链实现对原型属性和方法的继承,用借用构造函数模式实现对实例属性的继承。
这样既通过在原型上定义方法实现了函数复用,又能保证每个实例都有自己的属性

function Person(name) {
  this.name = name
  this.hobby = ["旅游","看电影"]
}
function CallThis(name) {
  Person.call(this, name)
}
CallThis.prototype = new Person();

let LJJ = new CallThis("刘家军")
LJJ.hobby.push("敲代码")
console.log(LJJ);
let YH = new CallThis("袁姮")
console.log(YH);

输出:
在这里插入图片描述
我们把这个组合继承和之前的两个原型链继承和借用构造函数继承进行比较
不难发现组合继承融合了他们的优点,成为javascript中最常用的继承模式
预知后事如何,且听下次分解

猜你喜欢

转载自blog.csdn.net/qq_42911663/article/details/85499571