JavaScript中继承分为两类,首先是对于对象内容的继承
1 var person={ 2 name:"人类", 3 age:88, 4 birth:1900, 5 run: function(){ 6 console.log(this.name+" is running"); 7 } 8 } 9 var json = { 10 name:"jason" 11 } 12 json.__proto__=person;
使用__proto__方法继承对象,如果这时输出json.age,或者使用下面的run方法,则调用的是json的内容,同时run方法中的this.name调用的是json中的name。因此可以判断出,对象的继承是覆盖性的,继承所有属性的同时,用自身同名内容覆盖继承的内容。
如果我们先后继承两次的话,如下
1 var person={ 2 name:"人类", 3 age:88, 4 birth:1900, 5 xp:"人类", 6 run: function(){ 7 console.log(this.name+" is running"); 8 } 9 } 10 var bird={ 11 name:"鸟类", 12 age:8, 13 birth:2010, 14 fly: function(){ 15 console.log(this.name+" is flying"); 16 } 17 } 18 var json = { 19 name:"jason" 20 } 21 json.__proto__=person; 22 json.__proto__=bird;
这时我们如果想调用run函数会发现调用失败,而同时试图输出xp的时候也会发现输出undefined。说明如果我们使用继承来定义对象的话,同时只能继承一个对象。
除去对象的继承之外,还有的就是类的继承。
在此之前,需要先了解一下类的定义方法。在JavaScript中,类有两种定义方法如下所示:
function per(name){ this.name=name; } per.prototype.hello = function(){ alert("你好 "+this.name); }//一种是先定义部分,然后添加其他方法 function par(name){ this.name=name; this.hello=function(){ alert("Hello "+this.name); } } var student=new per("student"); student.hello(); var man=new par("man"); man.hello();
当然,这两种是在ES6引入class之前,人们所为了定义类这种结构来做出的决策。在ES6中引入类之后,我们就可以正常的用类似java中的方法来定义类:
class student{ constructor(name,age) { this.name=name; this.age=age; } getStudent(){ alert(this.name+"今年"+this.age+"岁"); } } var s=new student("小明",18); s.getStudent();
继承的方式也就和Java中相同,都是采用extends关键词来完成:
class person{ constructor(name) { this.name=name; } } class student extends person{ constructor(name,grade) { super(name); this.grade=grade; } hello(){ alert(this.name+"同学现在在读"+this.grade); } } var s=new student("小明","大四"); s.hello();
对于我们上边的这个例子来说,person类就叫做student类的原型。
在JavaScript中,存在着一条原型链。如果我们打开浏览器,寻找元素,会发现他们都有__proto__的内容,这些就代表着他们的原型,而所有的原型链在JavaScript中都是指向最终的对象——Object的。而由于Object下面的方法也有继承,也有原型,最终还是指向Object,因此我们的原型链是“循环”的,是没有”尽头”的。
原文:https://www.cnblogs.com/winteriscomming/p/15114564.html