代码理解ES6中的class类与继承

200 阅读3分钟
class Animal {//创建Animal类            
    constructor(species) { //constructor方法是类的构造函数的默认方法,通过new命令生成对象实例时,自动调用该方法。                
        this.species = species //Animal类 自己定义了species 属性            
    }            
    eat() { //Animal类 自己又定义了eat 方法                
        console.log('eateat')            
    }            
    static isAnimal() { //静态方法需要 static 修饰                
        console.log('i don\'t know ')            
    }        
}        
class Lion extends Animal {//创建Lion类            
    constructor(species, size) { //constructor方法如果没有显式定义,会隐式生成一个constructor方法。所以即使你没有添加构造函数,构造函数也是存在的。constructor方法默认返回实例对象this,但是也可以指定constructor方法返回一个全新的对象,让返回的实例对象不是该类的实例。                
        // return new Animal();// 这里没有用this哦,直接返回一个全新的对象                
        super(species)//继承父类的属性,必须写在任何this的开头,不然会报错                
        this.size = size  // Lion类 自己又定义了size 属性                
        // 继承和定义属性都在 构造函数 constructor 中继承或定义            
    }            
    eat() {//重写原型方法                
        console.log('eatmeat')            
    }        
}        
let lion = new Lion('Feline family', 'big')        
let animal = new Animal('Feline big')        
console.log(lion.species) //继承了父类的属性        
console.log(lion.size) //Lion类的属性        
Animal.isAnimal() //isAnimal方法是静态方法, Animal类中有这个方法,所以能调用,animal 实例调用不了 animal.isAnimal() 会报错        
Lion.isAnimal() //isAnimal方法是静态方法, Lion 类中继承了这个方法,所以能调用,lion 实例调用不了 lion.isAnimal() 会报错        
// animal.isAnimal()  //Uncaught TypeError: animal.isAnimal is not a function        
// lion.isAnimal()  //Uncaught TypeError: lion.isAnimal is not a function        
// 类的所有方法都定义在类的prototype属性上面,所有类中定义的方法都会被实例继承,如果在类方法前面加上static关键字就不会被实例继承了。        
// 静态方法是直接通过类名来调用。Animal.isAnimal() Lion.isAnimal() 能调用成功        
// Animal.eat() //类的所有方法都定义在类的prototype属性上面,  Animal.eat() 调用会报错        
// Lion.eat() // 类的所有方法都定义在类的prototype属性上面,  Lion.eat() 调用会报错        
lion.eat() //eatmeat        
animal.eat()  // eateat        
//constructor中定义的属性可以称为实例属性(即定义在this对象上),constructor外声明的属性都是定义在原型上的,可以称为原型属性(即定义在class上)。hasOwnProperty()函数用于判断属性是否是实例属性。其结果是一个布尔值,true说明是实例属性,false说明不是实例属性。in操作符会在通过对象能够访问给定属性时返回true,无论该属性存在于实例中还是原型中。        
console.log(lion.hasOwnProperty("size"));//true        
console.log(lion.hasOwnProperty("size"));//true        
console.log(lion.hasOwnProperty("eat"));//false        
console.log("size" in lion);//true        
console.log("size" in lion);//true        
console.log("eat" in lion);//true        
console.log("eatSize" in lion);//false        
//类的所有实例共享一个原型对象,它们的原型都是Person.prototype,所以proto属性是相等的        
var lion2 = new Lion('Feline family2', 'big2')        
console.log(lion.__proto__ === lion2.__proto__);//true        
//由此,也可以通过proto来为类增加方法。使用实例的proto属性改写原型,会改变Class的原始定义,影响到所有实例,所以不推荐使用!        
// 另外要理解的两点:1.实例属性指的是在构造函数方法中定义的属性和方法,每一个实例对象都独立开辟一块内存空间用于保存属性和方法。        
//                2.原型属性指的是用于创建实例对象的构造函数的原型的属性,每一个创建的实例对象都共享原型属性。