1 /**
2 * Created by 2016 on 2016/6/5.
3 */
4 //1、原型链继承
5 //把子类的原型,定义为超类的实例 通过原型来访问超类的方法和属性
6 function Person(){//超类
7 this.age = 40;
8 this.run = function(){
9 console.log("Person is running");
10 }
11 }
12 function Student(){}//子类
13 Student.prototype = new Person();//实现继承
14
15 //注意:如果要重写或者添加子类的方法,需要在继承之后。
16 //缺点:1、如果属性中存在引用类型的值,由于属性是共享的,修改属性会同步修改。
17 // 2、无法给超类的构造函数传递参数
18 // 3、无法实现多继承
19
20
21 //2、借用构造函数
22 //在子类的构造函数内部调用超类的构造函数。利用apply(obj,[])和call(obj,arg1,arg2)函数
23 function Person(){//超类
24 this.age = 40;
25 this.run = function(){
26 console.log("Person is running");
27 }
28 }
29
30 function Student(){
31 Person.call(this);//调用超类的构造函数,这里可以传递参数
32 }
33
34 var student = new Student();
35 student.run();//"Person is running"
36 //缺点:1、借用构造函数,导致所有的方法都在构造函数中定义,方法无法复用
37 // 2、超类原型中的方法和属性,对于子类来说是无法访问的,导致所有类型都必须使用构造函数模式。
38
39
40 //3、组合继承
41 //伪经典继承 将原型链继承和借用构造函数的继承组合起来使用。借用构造函数方式实现属性的继承,原型链的方式实现方法继承
42 //实现了方法的复用和属性的独立。组合继承是常用的继承方式
43 function Person(){
44 this.age = 40;
45 }
46 Person.prototype = {
47 constructor:Person,
48 run:function(){
49 console.log("Person is running");
50 }
51 };
52 function Student(){
53 Person.call(this);//继承属性
54 }
55 Student.prototype = new Person();//继承方法
56
57 //缺点:由于属性和方法分开继承,导致一定会调用两次的超类构造函数。可以使用寄生组合继承的方式优化。
58
59 //4、原型式继承
60 //基于原型继承,和原型链的继承相似,这里返回一个子类的实例
61 function object(o){
62 function F(){}//创建一个临时构造函数
63 F.prototype = o;
64 return new F();
65 }
66 //ECMAScript5对原型式继承进行了规范,可以使用Object.create()方法来继承。这个函数接收两个参数,用作子类原型的超类对象,和
67 // (可选的)为新对象指定的属性对象,看代码
68
69 var Person = {//超类
70 age:40,
71 run:function(){
72 console.log("Person is running");
73 }
74 };
75 var student = Object.create(Person,{age:30});
76 student.run();//Person is running
77 student.age;//30
78
79 //5、寄生继承
80 //使用一个函数来实现继承,函数参数为超类对象,通过复制超类对象——增强对象——返回结果对象的方式,来实现继承
81
82 function createObject(obj){
83 var newObj = object(obj);//创建新对象
84 newObj.run = function(){//增强对象
85 console.log("Person is running");
86 };
87 return newObj;//返回结果对象
88 }
89 var Person ={
90 age : 40,
91 walk : function(){
92 console.log("Person is walking");
93 }
94 };
95 var student = createObject(Person);
96 student.walk();
97 student.run();
98
99 //注意:这里传入的obj必须是实例,不能是构造函数。
100 //缺点:和借用构造函数方式一样,方法无法复用。
101
102
103 //6、寄生组合式继承
104 //避免组合式继承调用两次超类的构造函数,提高效率
105 function inheritPrototype(subType,superType){//继承原型函数,参数为子类,超类
106 var prototype = Object.create(subType.prototype);//生成超类的原型副本
107 prototype.constructor = subType;//将原型副本的constructor指向子类
108 subType.prototype = prototype;//指定子类的新原型,实现继承属性
109
110 }
111 function Person(){
112 thi.age = 40;
113 }
114 Person.prototype = {
115 run:function(){
116 console.log("Person is walking");
117 }
118 };
119 function Student(){
120 Person.call(this);
121 }
122 inheritPrototype(Student,Person);//继承超类(原型继承)
123 var student = new Student();
124 student.run();//"Person is walking"
125 student.age;//40
126
127 //继承的最有效方式