继承分为接口继承与实现继承
接口继承:继承方法签名
实现继承:继承实际的方法
ECMAScript 只支持实现继承,而其实现继承的主要是依靠原型链来实现的
继承:利用原型让一个引用类型继承另一个引用类型的属性和方法;
要实现理解继承,首先要理解原型链:
1.每个构造函数都有一个原型对象属性,这个属性指向构造函数的原型对象
2.每个函数的原型对象都有一个 constructor 属性,这个属性指向构造函数本身
3.每个实例(或对象)都有一个隐式原型属性(__proto__),这个隐式原型属性指向构造函数的原型对象
4.构造函数原型对象上的隐式原型属性(__proto__)指向 Object.prototype 即所有函数的默认原型都是Object 对象的实例
5.Object.prototype 上的隐式原型指向null
以上就是原型链的基础
原型继承,实质上是通过原型链来继承的
<script> function supertype() { this.supername = "huanying2015"; } supertype.prototype.getsuperName = function() { return this.supername; } function subtype() { this.subname = "aluoha"; } subtype.prototype = new supertype(); // 改变了原型链的指向 subtype.prototype.getsubname = function() { // 在原型上添加方法 return this.subname; } var instance = new subtype(); console.log(instance.getsuperName()); console.log(instance.getsubname()); </script>
2. 借用构造函数继承(经典继承)
1 <script> 2 function supertype() { 3 this.colors = ['red', 'gray', 'yellow']; 4 } 5 6 function subtype() { 7 supertype.call(this); 8 } 9 var instance = new subtype(); 10 instance.colors.push("green"); 11 12 console.log(instance.colors); 13 var instance1 = new subtype(); 14 console.log(instance1.colors); 15 </script>
1 <script> 2 function supertype(name) { 3 this.name = name; 4 this.sayName = function() { 5 return "你好," + this.name + ",欢迎来到地球!"; 6 } 7 } 8 9 function subtype() { 10 supertype.call(this, 'huanying2015'); // 借用构造函数,同时传递参数 11 this.age = 25; 12 } 13 var instance = new subtype(); 14 console.log(instance.sayName()); 15 console.log(instance.age); 16 </script>
备注:所有方法都在构造函数中,无法复用
3.组合继承(伪经典继承):将原型链和借用构造函数组合到一起
1 <script> 2 function supertype(name) { 3 this.name = name; 4 this.colors = ['red', 'green', 'blue']; 5 } 6 supertype.prototype.sayName = function() { 7 console.log(this.name); 8 } 9 10 function subtype(name, age) { 11 supertype.call(this, name); 12 this.age = age; 13 } 14 15 subtype.prototype = new supertype(); 16 subtype.prototype.constructor = subtype; 17 subtype.prototype.sayAge = function() { 18 console.log(this.age); 19 } 20 21 var instance = new subtype('huanying2015', 25); 22 instance.colors.push("gray"); 23 console.log(instance.colors); 24 instance.sayName(); 25 instance.sayAge(); 26 27 var instance1 = new subtype('aluoa', 27); 28 console.log(instance1.colors); 29 instance1.sayName(); 30 instance1.sayAge(); 31 </script>
4.原型式继承:
1 <script> 2 function object(o) { 3 function F() {}; 4 F.prototype = o; 5 return new F(); 6 } 7 8 var person = { 9 name: "huanying2015", 10 friends: ["zhangsan", "lisi", "wanger"], 11 } 12 person1 = object(person); 13 person1.name = 'jack'; 14 person1.friends.push("zhaoliu"); 15 16 person2 = object(person); 17 person2.name = 'Linbai'; 18 person2.friends.push("zhaozilong"); 19 20 console.log(person.friends); 21 console.log(person1.friends); 22 console.log(person2.friends); 23 console.log(person.name); 24 console.log(person1.name); 25 console.log(person2.name); 26 </script>
5.寄生是继承:
1 <script> 2 function createAnother(o) { 3 var clone = Object(o); 4 clone.sayhello = function() { 5 console.log("hello!这里是地球"); 6 } 7 return clone; 8 } 9 var person = { 10 name: "huanying2015", 11 friends: ["zhangsan", "lisi", "wanger"], 12 } 13 14 var person1 = createAnother(person); 15 person1.sayhello(); 16 </script>
6.寄生组合继承:
1 <script> 2 function supertype(name) { 3 this.name = name; 4 this.colors = ['red', 'blue', 'yellow']; 5 } 6 supertype.prototype.sayName = function() { 7 console.log(this.name); 8 } 9 10 function subtype(name, age) { 11 supertype.call(this, name); //第二次调用supertype() 12 this.age = age; 13 } 14 15 subtype.prototype = new supertype(); //第一次调用supertype() 16 subtype.prototype.constructor = subtype; 17 subtype.prototype.sayAge = function() { 18 console.log(this.age); 19 } 20 </script>
会两次调用supertype()构造函数
<script> function inheritPrototype(subtype, supertype) { var prototype = Object(supertype.prototype); // 创建对象 prototype.constructor = subtype; // 增强对象 subtype.prototype = prototype; // 指定对象 } </script>
这是是想寄生组合继承最简单的模式
1 <script> 2 function inheritPrototype(subtype, supertype) { 3 var prototype = Object(supertype.prototype); // 创建对象 4 prototype.constructor = subtype; // 增强对象 5 subtype.prototype = prototype; // 指定对象 6 } 7 8 function supertype(name) { 9 this.name = name; 10 this.colors = ['red', 'blue', 'yellow']; 11 } 12 supertype.prototype.sayName = function() { 13 console.log(this.name); 14 } 15 16 function subtype(name, age) { 17 supertype.call(this, name); 18 this.age = age; 19 } 20 21 inheritPrototype(subtype, supertype); 22 23 subtype.prototype.sayAge = function() { 24 console.log(this.age); 25 } 26 27 var person = new subtype('huanying2015', 25); 28 person.sayName(); 29 person.sayAge(); 30 </script>