【原型和原型链】类和继承

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaoermingn/article/details/80747174

一、定义“类” ——构造函数

我们知道,JavaScript中没有类的概念,我们只是通过函数来模仿类的行为,我们将它称之为构造函数


构造函数分两类,原生构造函数和自定义构造函数。原生构造函数像Array、Object,是执行环境自动提供的;自定义构造函数是我们自己来创建的


当你想用相同的属性和方法创建多个相似的对象时,构造函数是非常有用的。

定义构造函数的方法:

function Animal(name){
    //此判断是使用时缺省new关键词时的安全策略
    if(!(this instanceof Animal)){
        return new Animal(name);
    }

    this.name = name;
}

Animal.prototype = {
    eat: function(){
        console.log('I am eating');
    }
}

var dog = new Animal();

dog.eat(); // I am eating

在调用new创造实例时,做了下面几件事:

  1. 构造函数中的this指向当前出发执行的对象,即dog,所以在dog本身添加了属性name

  2. dog的__proto__指向Animal的prototype,对dog.__proto__中属性的修改会引起Animal中prototype的变化,从而使得所有由Animal创造的实例__proto__中的属性改变(引用类型,全都指向同一地址)

  3. dog的constructor属性指向Animal本身,因为dog的constructor指向Animal本身,所以我们可以通过instanceof来判断dog是否为Animal的实例,但是constructor可以被改写,所以通过instanceof来判断不一定准确


二、继承

在JavaScript中一切都是对象,当我们谈到继承,其实是对象从对象中的继承,而不是类从类中的继承

很多时候我们在创建多个具有相同属性的实例时,可能有几个具有自己特有的属性,所以我们需要先继承公共构造函数中的属性,然后改写自己特有的属性

继承写法:

function Animal(name){
    if(!(this instanceof Animal)){
        return new Animal(name);
    }
    this.name = name;
}

Animal.prototype = {
    eat: function(){
        console.log('I am eating');
    }
}

function Mammalia(name, age){
    this.name = name;
    this.age = age;
}

Mammalia.prototype = new Animal();

var dog = new Mammalia('hashiqi', 5);

最后生成的原型链如图:

这里写图片描述


三、ES6中的class

class一直是 JS 的关键字(保留字),但是一直没有正式使用,在ES6中终于使用到了它,通过class来定义构造函数,从语法上更加符合面向对象的写法

对目录一中代码的改写:

class Animal {
    constructor(name){
        this.name = name;
    }

    eat(){
        console.log('I am eating');
    }
}

var dog = new Animal();

dog.eat(); // I am eating

对目录二继承代码的改写:

class Animal {
    constructor(name){
        this.name = name;
    }
    eat(){
        console.log('I am eating');
    }
}

class Mammalia extends Animal {
    constructor(name, age){
        super(name);
        this.name = name;
        this.age = age;
    }
}

var dog = new Mammalia('hashiqi', 5);

注意:

  • 子类的constructor一定要执行super(),以调用父类的constructor
  • 继承的关键词是extends,不要忘记s
  • class是ES6提供的一种语法糖,其内部实现原理还是一样的

猜你喜欢

转载自blog.csdn.net/xiaoermingn/article/details/80747174