javascript设计模式-继承
javascript继承分为两种:类式继承(原型链、extend函数)、原型式继承(对继承而来的成员的读和写的不对等性、clone函数)。
- 类式继承-->prototype继承:
1 function Person(name){ 2 this.name = name; 3 } 4 Person.prototype.getName = function(){ 5 return this.name; 6 } 7 8 //继承 9 function Author(name,books){ 10 Person.call(this,name); 11 this.books = books; 12 } 13 Author.prototype = new Person(); 14 Author.prototype.constructor = Author; 15 Author.prototype.getBooks = function(){ 16 return this.books; 17 } 18 19 var author = new Author("zap","javascript程序设计"); 20 console.log(author);
- 类式继承-->extend函数:
1 function extend(subClass,superClass){ 2 var F = function(){}; 3 F.prototype = superClass.prototype; 4 subClass.prototype = new F(); 5 subClass.prototype.constructor = subClass; 6 7 subClass.superClass = superClass.prototype; 8 if(superClass.prototype.constructor == Object.prototype.constructor){ 9 superClass.prototype.constructor = superClass; 10 } 11 } 12 13 14 /*Class Person*/ 15 16 function Person(name){ 17 this.name = name; 18 } 19 Person.prototype.getName = function(){ 20 return this.name; 21 } 22 23 function Author(name,books){ 24 Author.superClass.constructor.call(this,name); 25 // Person.call(this,name); 26 this.books = books; 27 } 28 extend(Author,Person); 29 Author.prototype.getBooks = function(){ 30 return this.books; 31 } 32 33 var author = new Author("zap","javascript程序设计"); 34 console.log(author); 35 console.log(author.getName()); 36 console.log(author.getBooks());
- 原型式继承-->clone函数:(原型式继承更能节约内存)
1 var Person ={ 2 name:"zap", 3 age:"26", 4 toString:function(){ 5 console.log(this.name + "@" + this.age); 6 } 7 } 8 9 var author = clone(Person); 10 author.name = "zap"; 11 author.toString(); 12 13 function clone(object){ 14 function F(){} 15 F.prototype = object; 16 return new F; 17 }
附上以类式继承实现的就地编辑demo,原型式方式实现和类式继承方式相差无几,不在此列举。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>类式继承解决方案</title> 6 <style type="text/css"> 7 #doc{width:500px; height:300px; border:1px solid #ccc; margin:10px auto;} 8 </style> 9 </head> 10 <body> 11 <div id="doc"></div> 12 </body> 13 </html> 14 <script type="text/javascript"> 15 16 function EditInPlaceField(id,parent,value){ 17 this.id = id; 18 this.value = value || "default value"; 19 this.parentElement = parent; 20 21 this.createElements(this.id); 22 this.attachEvents(); 23 } 24 25 EditInPlaceField.prototype = { 26 createElements:function(id){ 27 this.createContainer(); 28 this.createShowPanel(); 29 this.createEnterPanel(); 30 this.createControlBtns(); 31 this.convertToText(); 32 }, 33 //创建容器 34 createContainer:function(){ 35 this.containerElement = document.createElement("div"); 36 this.parentElement.appendChild(this.containerElement); 37 }, 38 createShowPanel:function(){ 39 this.staticElement = document.createElement("span"); 40 this.containerElement.appendChild(this.staticElement); 41 this.staticElement.innerHTML = this.value; 42 }, 43 createEnterPanel:function(){ 44 this.fieldElement = document.createElement("input"); 45 this.fieldElement.type = "text"; 46 this.fieldElement.value = this.value; 47 this.containerElement.appendChild(this.fieldElement); 48 }, 49 createControlBtns:function(){ 50 this.saveButton = document.createElement("input"); 51 this.saveButton.type = "button"; 52 this.saveButton.value = "Save"; 53 this.containerElement.appendChild(this.saveButton); 54 55 56 this.cancelButton = document.createElement("input"); 57 this.cancelButton.type = "button"; 58 this.cancelButton.value = "Cancel"; 59 this.containerElement.appendChild(this.cancelButton); 60 }, 61 attachEvents:function(){ 62 var that = this; 63 addEvent(this.staticElement,"click",function(){that.convertToEditable();}); 64 addEvent(this.saveButton,"click",function(){that.save();}); 65 addEvent(this.cancelButton,"click",function(){that.cancel();}); 66 }, 67 convertToEditable:function(){ 68 this.staticElement.style.display = "none"; 69 this.fieldElement.style.display = "inline"; 70 this.saveButton.style.display = "inline"; 71 this.cancelButton.style.display = "inline"; 72 73 this.setValue(this.value); 74 }, 75 save:function(){ 76 this.value = this.getValue(); 77 var that = this; 78 var callback = { 79 success:function(){ 80 that.convertToText(); 81 }, 82 failure:function(){ 83 alert("Error saving value."); 84 } 85 }; 86 87 ajaxRequest("get","save.php?id=",callback); 88 }, 89 cancel:function(){ 90 this.convertToText(); 91 }, 92 convertToText:function(){ 93 this.fieldElement.style.display = "none"; 94 this.saveButton.style.display = "none"; 95 this.cancelButton.style.display = "none"; 96 this.staticElement.style.display = "inline"; 97 98 this.setValue(this.value); 99 }, 100 setValue:function(value){ 101 this.fieldElement.value = value; 102 this.staticElement.innerHTML = value; 103 }, 104 getValue:function(){ 105 return this.fieldElement.value; 106 } 107 } 108 109 //事件绑定 110 function addEvent(element,type,fn){ 111 if(element.addEventListener){ 112 element.addEventListener(type,fn,false); 113 }else if(element.attachEvent){ 114 element.attachEvent("on" + type,fn); 115 }else{ 116 element["on" + type] = fn; 117 } 118 } 119 //ajax请求 120 function ajaxRequest(type,url,callback){ 121 callback.success(); 122 } 123 //extend 124 function extend(subClass,superClass){ 125 var F = function(){}; 126 F.prototype = superClass.prototype; 127 subClass.prototype = new F(); 128 subClass.prototype.constructor = subClass; 129 130 subClass.superClass = superClass.prototype; 131 if(superClass.prototype.constructor == Object.prototype.constructor){ 132 superClass.prototype.constructor = superClass; 133 } 134 } 135 136 //子类 137 function EditInPlaceArea(id,parent,value){ 138 EditInPlaceArea.superClass.constructor.call(this,id,parent,value); 139 }; 140 extend(EditInPlaceArea,EditInPlaceField); 141 142 //override 143 EditInPlaceArea.prototype.createShowPanel = function() { 144 this.staticElement = document.createElement("p"); 145 this.containerElement.appendChild(this.staticElement); 146 this.staticElement.innerHTML = this.value; 147 } 148 149 EditInPlaceArea.prototype.createEnterPanel = function(){ 150 this.fieldElement =document.createElement("textarea"); 151 this.fieldElement.value = this.value; 152 this.containerElement.appendChild(this.fieldElement); 153 } 154 155 EditInPlaceArea.prototype.convertToEditable = function(){ 156 this.staticElement.style.display = "none"; 157 this.fieldElement.style.display = "block"; 158 this.saveButton.style.display = "inline"; 159 this.cancelButton.style.display = "inline"; 160 161 this.setValue(this.value); 162 } 163 164 EditInPlaceArea.prototype.convertToText = function(){ 165 this.fieldElement.style.display = "none"; 166 this.saveButton.style.display = "none"; 167 this.cancelButton.style.display = "none"; 168 this.staticElement.style.display = "block"; 169 this.setValue(this.value); 170 } 171 172 var titleClassical = new EditInPlaceArea("titleClassical",document.getElementById("doc"),"title here"); 173 174 </script>