ES6学习05--继承和ES5继承的区别

发布于:2022-12-16 ⋅ 阅读:(378) ⋅ 点赞:(0)

1.ES5 继承回顾

在ES5 中,我们使用组合继承,通过原型链继承继承原型上的公共属性和公共方法,而通过经典继承函数继承实例属性。继承中,如果不把子类的构造函数再指回自身构造函数,就会很混乱,子类的类型居然是父类类型。如下案例,如果不使用该语句:Dog.prototype.constructor= Dog,那么Dog的实例居然是Animal。

function Animal(name,age,weight){
  this.name=name
  this.age=age
  this.weight=weight
}
Animal.prototype={
  constructor:Animal,
  sayName(){
    console.log(this.name);
  }
}
function Dog(name,age,weight,type){
  // 借用构造函数继承属性
  Animal.call(this,name,age,weight)
  this.type=type
}
// 继承父类的方法
Dog.prototype=new Animal()
// 将子类构造函数指回自身构造函数
Dog.prototype.constructor= Dog
let d1 = new Dog('旺财',5,'6kg','柴犬')
console.log(d1);
d1.sayName()

2. ES6 类

在ES5中,子类的方法和实例属性都需要分别继承父类的原型和构造函数,显而易见,这很麻烦,也容易让我们造成混乱。
为了解决继承的麻烦,ES6 引进了类的概念,定义一个类可以通过class关键字。

如何定义一个类?
构造函数和实例方法可以直接定义在类中,而不需要分别定义

class Person {
  // construtor是类的默认方法,必须有
  constructor(name, age) {
  //实例的私有属性
    this.name = name
    this.age = age
  }
  
  // 实例方法 类似于存在Person.prototypez中  
  sayName() {
    console.log(this.name);
  }
  // static 定义静态方法 只能由类调用
  static personMethod() {
    console.log('这是静态方法');
  }
  // static 定义静态属性 只能由类调用
  static personAttr = '静态属性'
}
//创建类的实例
let p=new Person('zhangsan',12);
let p2=new Person({});
console.log(p.sayName===p2.sayName)// true,存放在原型对象中的是同一个方法

敲重点!!!
在类中定义实例的属性,基本类型值属性是公共的(但是,当实例修改基本类型值属性时,该属性变成私有属性。),而引用类型值属性为私有

class Person{
  //定义实例属性
  //基本类型值为公共属性 但是,当实例修改基本类型值属性时,该属性变成私有属性。
  test=1
  //引用类型值为私有属性
  test1=['hello']
}
let p1 = new Person('zhangsan',12)
let p2 = new Person('lisi',18)
console.log(p1.test === p2.test);  // true
console.log(p1.test1 === p2.test1); //false
//修改p1.test值
p1.test=2
console.log(p1.test === p2.test);//false p1.test变成私有属性

3. ES6 继承

子类继承父类,用关键字extends声明。
重要的还有一个东西,在子类的constructor函数中,必须使用super,通过父类的构造函数完成塑造。

class Animal{
  constructor(name,age,weight){
    this.name=name;
    this.age=age;
    this.weight=weight
  }
  sayName(){
    console.log(this.name);
  }
  static animalmethod(){
    console.log('Animal静态方法');
  }
}
// 继承 用关键字extends声明
class Dog extends Animal{
  constructor(name,age,weight,type){
    super(name,age,weight)
    this.type=type
  }
}
// 创建子类实例
let dog = new Dog('虎芽',3,'7kg','哈士奇')
dog.sayName()
console.log(Dog.__proto__ === Animal);   //true 判断Dog的原型是否为Animal
console.log(Dog.prototype.__proto__===Animal.prototype)//true Dog的原型的原型(Animal的原型)是否为Animal的原型,答案当然为true
console.log(dog instanceof Animal);   // true 判断子类的实例dog是否在Animal的原型链上

网站公告

今日签到

点亮在社区的每一天
去签到