ES6继承CLASS
class Parent{ constructor(n) { this.name = n } skill(){ console.log(this.name + "是鉴定师") //大老王是鉴定师 } } class Child extends Parent{ //继承了构造函数Child的实例的原型指向parent constructor(n){ super(n)// } skill(){ //不写这个方法的话,他就会继承父亲的方法,写了就执行自己的 console.log(789)//改写不会影响parent //789 } } var p = new Parent("大老王"); console.log(p)// Parent {name: "大老王"} p.skill(); var c = new Child("小老王"); console.log(c) //Child {name: "小老王"} c.skill();
混合继承:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> </body> <script> // 混合继承:构造函数继承+原型对象继承 // 优点:既能继承构造函数又能继承原型,方便传参,多继承 // 缺点:复杂 // 常用的继承方式之一 function Parent(n){ this.name = n; } Parent.prototype.skill = function(){ console.log(this.name + "是鉴定师");//parent上有原型方法; //大老王是鉴定师 } function P2(){ this.a = 10; } P2.prototype.init = function(){ console.log("hello") } function Child(n){ //需要Child继承构造函数中的属性,以及prototype的方法; Parent.call(this,n) //继承属性:在Child里面执行Parent;执行时用call将this的指向改变,同时将参数发过去。这时候就将构造函数中的Name继承过来了。 P2.call(this) //同理,注意这里没有参数,所有this后不需要添加一个参数。 } for(var i in Parent.prototype){ //使用原型对象形式做一个深拷贝,拷贝Parent的原型对象 Child.prototype[i] = Parent.prototype[i] //使 Child.prototype的值与Parent.prototype的值一样; } for(var i in P2.prototype){ Child.prototype[i] = P2.prototype[i] } Child.prototype.skill = function(){ //对Child中的prototype的方法进行修改,不会影响Parent中的原型方法 console.log(123) } var p = new Parent("大老王"); console.log(p) //Parent(构造函数) p.skill(); //大老王是鉴定师 var c = new Child("小老王"); console.log(c)//Child(构造函数) c.skill();//123 c.init();//hello </script> </html>
原型继承:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> </body> <script> // 原型对象继承:继承原型 // 优点:简单,方便,可以继承原型身上的方式和属性 // 缺单:只能继承原型,不方便传参 function Parent(n){ this.name = n; } Parent.prototype.skill = function(){ console.log(this.name + "是鉴定师"); } function Child(n){} // 注意:对象的深浅拷贝 // Child.prototype = Parent.prototype; for(var i in Parent.prototype){ Child.prototype[i] = Parent.prototype[i]; } // Child.prototype.skill = function(){ // console.log("采矿"); //不会影响Parent中的方法。 var p = new Parent("大老王"); console.log(p) p.skill(); var c = new Child("小老王"); console.log(c) c.skill(); </script> </html>
原型链继承:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> </body> <script> // 原型链继承:通过给Child设置原型为Parent的实例的方式,给Child添加了一层原型链的方式 // 优点:既能继承原型,又能继承构造函数 // 缺点:复杂,不方便传参 function Parent(n){ this.name = n; } Parent.prototype.skill = function(){ console.log(this.name + "是鉴定师"); } function Child(){} Child.prototype = new Parent("小老王"); // Child.prototype.skill = function(){ // console.log(12312312) //不会影响所继承的父级 // } var p = new Parent("大老王"); console.log(p) //Parent(构造函数) p.skill(); //大老王是鉴定师 // p是实例(对象),有__proto__属性,指向Parent.prototype var c = new Child(); console.log(c); //Child(构造函数) c.skill(); //小老王是鉴定师 //自己可设置skill的方法,那样就不会继承了父级的方法 // c是实例(对象),有__proto__属性,指向Child.prototype,是Parent的实例(对象),有__proto__属性,指向Parent.prototype </script> </html>
实例与构造函数的关系
<script> function Parent(n){ this.name = n; } Parent.prototype.skill = function(){ console.log(this.name + "是鉴定师"); } function P2(){ this.a = 10; } P2.prototype.init = function(){ console.log("hello") } function Child(n){ Parent.call(this,n) P2.call(this) } Child.prototype = new Parent(); var p = new Parent("大老王"); var c = new Child("小老王"); console.log(c) //可以看到c的原型指向parent的实例Parent; //Parent的实例指向了自己的构造函数。 var a = new Array(); //左边是父 括号中是子元素,左边是个原型对象,右边是个实例 console.log(Parent.prototype.isPrototypeOf(c)) //t Child的实例是否指向Parent的原型。或者说是Parent的构造函数是否被c指向。 console.log(Parent.prototype.isPrototypeOf(a)) //f console.log(Array.prototype.isPrototypeOf(a)) //t 数组属于Array的这个原型,所以为true console.log(Object.prototype.isPrototypeOf(a)) //t console.log(Object.prototype.isPrototypeOf(c)) //t console.log(Object.prototype.isPrototypeOf(p)) //t //所有的实例,对象都属于object,所以那object测都是true; //左边是子右边是父。左边是实例,右边不是对象是构造函数本身 console.log(c instanceof Child); //t检测c是否是从构造函数child中来的; console.log(c instanceof Parent); //t检测c是否是从构造函数parent中来的;因为他是继承来的; console.log(c instanceof Array); //f console.log(c instanceof Object); //t console.log(p instanceof Child); //f </script>