怎么理解js的原型链继承?

前言

了解java等面向对象语言的童鞋应该知道。面向对象的三大特性就是:封装,继承,多态。

今天,我们就来聊一聊继承。但是,注意,我们现在说的是js的继承。

在js的es6语法出来之前,我们想实现js的继承关系,需要借助于原型链。之前的文章,我有讲过原型和原型链的概念。在这,再重新回顾一下。

  1. js中万物皆对象,每个对象都有一个隐式原型 __proto__ ,指向创建它的构造函数的原型对象。
  2. 函数(构造函数)除了有一个隐式原型对象,还有一个属性prototype,它指向一个对象,这个对象就是原型对象,也叫显式原型。
  3. 原型对象有一个属性constructor,它指向这个构造函数本身。

而原型链,就是为了实现js的继承,把实例对象的__proto__属性一层一层的指向它的构造函数的原型对象,直到它(Object.prototype)的原型对象为null。

举例分析

我们现在定义一个构造函数Person作为父类,传入一个name属性,给原型对象添加一个getName的方法。

function Person(name){
    this.name = name;
}

Person.prototype.getName = function(){
    console.log(`姓名:${this.name}`);
}

然后再定义一个构造函数Student,用以继承父类Person

function Student(name){
    //此处可以通过call方法来改变this的指向
    Person.call(this,name);
    //this.name = name;
}

var student = new Student("小明");

注意,此时我们只是调用了Person的构造函数,不等同于继承了Person。

可以通过打印 student实例对象来看它的原型链关系:

student  =>  Student.prototype => Object.prototype => null

这不是我们想要的结果,我们需要把原型链的继承关系改为这样的:

student  =>  Student.prototype => Person.prototype => Object.prototype => null

因此,我们需要把Student的原型指向父类Person的一个实例对象:

//创建一个父类构造函数的实例person
var person = new Person();
//把Student的原型指向新创建的 person实例
Student.prototype = person;
//同时需要把Student的构造函数修正为Student,
//因为此时Student的构造函数为Person,可自行 console.log(Student.prototype.constructor)查看
Student.prototype.constructor = Student;

//此时就可以正常的调用父类的方法了
student.getName(); //姓名:小明

以上,就可以实现js基于原型链的继承,这是在es6的class概念出来之前。在es6之后,就可以通过class的extends来实现继承。其实,这只是js的语法糖,在js引擎内部帮你实现了原型链的继承关系。

大胆猜测一下,es6这样的语法设计,也是为了迎合大部分面向对象的程序员吧。。。(感兴趣的小伙伴可以了解下typescript和es6)

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 白蝶悠然拂绿留, 蜗牛缓慢独行游。 蜜蜂吻蕊痴心恋, 蚂蚁攀丛自是牛。 鲁蕴20190606
    会飞的鼯鼠阅读 288评论 4 2
  • 去寻找一种自由的形态 追寻源自生命的渴望 在点滴的时光中 去享受 去追求 去生活 至于其他的窘迫 也许只是外界所赋...
    拥抱Mza阅读 129评论 0 1
  • 我本将心向明月,奈何明月照沟渠。 白素是一个再普通不过的女子。温婉而本分的默默做着一个女子该做的事。听了家里的话而...
    金面笑飞侠阅读 317评论 0 1
  • 百日计划第二十九天:假期到了,聊聊孩子做家务的事吧。劳动能力是生存能力的基础和核心内容。让孩子参与到家务中,可以培...
    微露清愁阅读 283评论 0 0