JavaScript 继承的几种模式
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript 继承的几种模式相关的知识,希望对你有一定的参考价值。
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 //继承的最有效方式
以上是关于JavaScript 继承的几种模式的主要内容,如果未能解决你的问题,请参考以下文章