js实现继承
es6之前的作法: 方法一:原型链 (与java的类多层继承思想类似,python可以多重继承,MixIn是常用的设计思想) 缺点: 当父级的属性有引用类型的时候,任意一个实例修改了这个属性,其他实例都会受影响 function SuperType() { this.property = true; } SuperType.prototype.getSuperValue = function() { return this.property; } function subType() { this.property = false; } //继承了SuperType SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function (){ return this.property; } var instance = new SubType(); console.log(instance.getSuperValue());//true 方法二:借用构造函数 缺点:创建多个实例 , 父类的方法会被创建多次。instance1.colors == intance2.colors // false function SuperType(){ this.colors = ["red","blue","green"]; } function SubType(){ SuperType.call(this);//继承了SuperType } var instance1 = new SubType(); instance1.colors.push("black"); console.log(instance1.colors);//"red","blue","green","black" var instance2 = new SubType(); console.log(instance2.colors);//"red","blue","green" 方法三:组合继承 缺点: 父类的构造器被调用了两次 function SuperType(name) { this.name = name; this.colors = ["red","blue","green"]; } SuperType.prototype.sayName = function() { console.log(this.name); } function SubType(name, age) { SuperType.call(this,name);//继承属性 this.age = age; } //继承方法 SubType.prototype = new SuperType(); Subtype.prototype.constructor = Subtype; Subtype.prototype.sayAge = function() { console.log(this.age); } var instance1 = new SubType("EvanChen",18); instance1.colors.push("black"); consol.log(instance1.colors);//"red","blue","green","black" instance1.sayName();//"EvanChen" instance1.sayAge();//18 var instance2 = new SubType("EvanChen666",20); console.log(instance2.colors);//"red","blue","green" instance2.sayName();//"EvanChen666" instance2.sayAge();//20 方法四:原型式继承 用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象,结果是将子对象的__proto__指向父对象 缺点:共享引用类型 (相互影响) function object(o) { function F(){} F.prototype = o; return new F(); } //示例 var person = { name:"EvanChen", friends:["Shelby","Court","Van"]; }; var anotherPerson = Object.create(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); var yetAnotherPerson = Object.create(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("Barbie"); console.log(person.friends);//"Shelby","Court","Van","Rob","Barbie" 方法五:寄生组合式继承 改进组合继承,利用寄生式继承的思想继承原型 function inheritPrototype(subType, superType){ var protoType = Object.create(superType.prototype); //创建对象 protoType.constructor = subType; //增强对象 subType.prototype = protoType; //指定对象 } function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ alert(this.name); } function SubType(name, age){ SuperType.call(this, name); this.age = age; } inheritPrototype(SubType, SuperType) SubType.prototype.sayAge = function(){ alert(this.age); } var instance = new SubType("Bob", 18); instance.sayName(); instance.sayAge(); ====Es6class继承 继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的 继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则) 如果子类想要继承父类的方法,同时在自己内部扩展自己的方法,利用super 调用父类的构造函数,super 必须在子类this之前调用 // 父类有加法方法 class Father{ constructor(x,y) { this.x = x ; this.y = y ; } sum() { console.log(this.x + this.y); } } // 子类继承父类加法的方法, 同时 扩展减法方法 class Son extends Father { constructor (x,y){ // 利用super调用父类的构造函数 // super必须在子类this之前调用 super(x,y); this.x = x; this.y = y; } subtract(){ console.log(this.x - this.y); } } var son = new Son(20,10); son.subtract();//10 son.sum(); //30