javascript进阶学习:关于原型和原型链的土话讲解,以及如何基于原型链实现继承
原型和原型链是js实现继承的一个重要特性,也可能是面试必问的问题,有很多这方面的讲解,但是都太让人费劲,小编试着用简单的语言来描述出来
本文我们的目标就是理解什么是原型链,以及如何通过原型链来实现类的继承
假如我们要实现一个Animal类,我们会怎么做呢?很简单,相信大家都知道,如下
function Animal() { } Animal.prototype.eat=function () { console.log("作为动物,我必须要学会进食") } Animal.prototype.run=function () { console.log("作为动物,我必须要学会跑") } var dog=new Animal() dog.eat() dog.run()
函数Animal 我们称为构造函数
这个构造函数的属性prototype,我们称为原型或原型对象(实际就是一个普通对象)
一个类我们可以看做由这两部分构成,构造函数和原型对象
变量dog是类的1个实例,拥有类的原型对象的属性(一些值和一些方法)
接下来,我们把dog打印出来,看看都有什么。这块不重要,了解就好,不要有压力
console.log(dog) //显示dog拥有该属性 __proto__
我们发现dog这个实例拥有一个__proto__属性,而且这个__proto__属性等于类的原型对象
也就是说实例的__proto__属性指向这个实例所属类的原型对象prototype
console.log(dog.__proto__===Animal.prototype) //true
我们再把Animal.prototype原型对象打印出来看看都有什么
console.log(Animal.prototype) //eat: ƒ () //run: ƒ () //constructor: ƒ Animal() //__proto__: Object
可以看到除了我们自定义的eat和run方法外,还有一个constructor属性,指向构造函数,原型对象也有一个__proto__属性,实际每个对象都有
结论:默认情况下类的原型对象拥有一个constructor属性,指向构造函数
console.log(Animal.prototype.constructor===Animal)
简单点,我们知道一个类由构造函数和原型对象构成就好了,类的实例会从原型对象那里继承一些属性和方法
那怎么实现继承呢?如果子类的原型对象,能够从父类那里复制过来一些属性,不就完成了继承吗
我们再添加一个Dog类,期望它能够继承Animal类,
function Animal() { } Animal.prototype.eat=function () { console.log("作为动物,我必须要学会进食") } Animal.prototype.run=function () { console.log("作为动物,我必须要学会跑") } //新增Dog的构造函数 function Dog() { } //Dog的原型对象先从Animal类那里复制一部分属性及方法,也就是对Animal类进行实例化 Dog.prototype=new Animal() //上面的操作会把prototype.constructor给覆盖,所以手动更新一下 Dog.prototype.constructor=Dog //为Dog对象添加自己的方法 Dog.prototype.say=function () { console.log("我说话就是汪汪汪") } var jinmao=new Dog() //Dog实例拥有以下3个方法,实现了继承 jinmao.eat() jinmao.run() jinmao.say()
实现Dog继承于Animal,实际就是Dog的原型对象从Animal那里复制过来一部分属性和方法,也就是实例化一个Animal
这样Dog.prototype就拥有Animal的属性和方法了,Dog.prototype就是一个普通的对象,我们可以给它增加新的属性,比如上面增加了一个say属性,只是这个属性对应的是一个函数,我们称这个属性为方法,实际就是为原型对象增加一个属性
我们打印下面的值看看效果
console.log(jinmao.__proto__===Dog.prototype) //true console.log(Dog.prototype.__proto__===Animal.prototype) //true console.log(Animal.prototype.__proto__===Object.prototype) //true,Animal的原型对象是一个普通对象,他继承于Object对象 console.log(Object.prototype.__proto__) //null,Object.protype是最顶级的对象,他不继承于别的对象,因此为null
实例jinmao的__proto__指向子类Dog的原型对象
子类Dog的原型对象的__proto__又指向父类Animal的原型对象
Animal的原型对象是一个普通对象,它的__proto__指向Object的原型对象
Object的原型对象是顶级对象,其__proto__为null
__proto__属性就像一个链条一样,将实例、子类、父类、父类的父类.......连接起来,这应该就是原型链的直观意义了吧
以上就是关于原型链和继承的简单理解,为了方便理解,并没有举复杂的例子,希望能帮助大家理解核心概念
点赞(0)