JS中构造函数/类/继承

157 阅读2分钟

1. ES5的构造函数(继承)

  • ES5中创建一个实例,通过构造函数

1.1 原型链概念

//类中创建的实例有两种属性,一种是实例身上自己的 一种是公共的

function Animal(){
    this.type = '哺乳类';
}

// 每一个类都有一个原型 是一个对象
Animal.prototype.eat = function(){
    console.log('eat');
}

let animal = new Animal;

animal.eat();    //eat 有eat方法,但不是实例上的属性

//监测是否实例上自身的属性
console.log(animal.hasOwnProperty('type'));   //是实例上的 true
console.log(animal.hasOwnProperty('eat'));    //eat是公共上的 false

//非实例上的属性
console.log(animal.__proto__.hasOwnProperty('eat'));    //true
console.log(animal.__proto__ === Animal.prototype);    //true

// 类上有一个属性 constructor,在prototype这个对象上

console.log(animal.constructor === animal.__proto__.constructor);   // true
console.log(Animal.prototype.__proto__ === Object.prototype);       // true
console.log(Object.prototype.__proto__);  //null 

1.2 构造函数的继承

// 抽象类 可以被继承不能被实例化
function Animal() {
    if(new.target === Animal){      //不希望这个Animal被new
        throw new Error('animal类不能被new,可以被继承');
    }
    this.type = '哺乳类';
}

Animal.prototype.eat = function(){
    console.log('eat');
}

function Tiger() {
    console.log(this);   //此处的this是tiger
    Animal.call(this);   //把tiger传入Animal替换this,继承type='哺乳类'
}

let tiger = new Tiger;

// 此时tiger还要继承Aniaml的公共属性
Tiger.prototype.__proto__ = Animal.prototype;
Object.setPrototypeOf(Tiger.prototype, Animal.prototype);  // ES6写法等价上句
tiger.eat();   // eat

console.log(tiger.type);   //哺乳类

2. ES6中的类

2.1 类的属性

class Animal{
    constructor(){
        this.type = '哺乳类'   //继承之后是实例上的属性
        this._age = 100;
    }
    
    get a(){         // 原型上属性   new出来调用
        return this._age;
    }
    
    set a(newAge){
        this._age = newAge;
    }
    
    static flag1() {}     // 类上静态方法
    
    static get flag(){
        return '动物';   // 静态属性
    }
    
    eat(){   //这里声明的变量都是当前类的原型上的
        console.log(eat)
    }
}

let animal = new Animal;
animal.eat();   // eat

console.log(Animal.a)   // undefined 不是类上的属性 类上用static

console.log( animal.hasOwnProperty('a') )   // false 不是实例上属性

console.log(Animal.flag)   //动物

animal.a = 0203;
console.log(animal.a)  //0203

2.2 类的继承

// ES6中继承 (做了什么)
// 1. Tiger.__proto__ = Animal
// 2. Animal.call(this)
// 3. Tiger.prototype = Object.create(Animal.prototype)

class Tiger extends Animal{
    constructor(){   // 使用this之前必须调用super
        super();     // 即:Animal.call(this)   super指的就是animal父类,this默认指向父类
        console.log(this)    // {type : 哺乳类}
    }
    
    static getFlag(){
        return super.flag   // 静态方法中的super指向的是父类
    }
    
    eat(){   // 子类中重写eat
        super.eat()  // 去找父类的原型   
    }
}

console.log(Tiger.flag)   // 动物  第一步

let tiger = new Tiger();
console.log(tiger.type);  // 哺乳类  第二步

console.log(tiger.eat());  // eat 第三步

console.log(Tiger.getFlag())   // 动物

3. 关于constructor

  • 什么是constructor?
    • 一种用于创建或者初始化class对象的特殊方法
    • 生成对象,基于构造函数的原型

    1. 函数模板,用来创建对象,构造器 new的过程 构造函数
    1. 是一个属性,告诉实例,谁创造了实例,指向创造儿子的爹

  • 函数的解释