寫一個算法,有時候可以用簡單的方法就可以寫出來,但是只能針對特定的環境,如果要能夠適應不同的環境,就需要對算法進行優化,在優化的過程中,你會覺得非常神奇,下面來看一個簡單的四則運算的算法編寫方式:
1.簡單粗暴的實現:直接創建一個對象,在對象上直接掛載加減乘除方法
1 <script> 2 var per = { 3 add: function(n1, n2) { 4 return n1 + n2; 5 }, 6 sbb: function(n1, n2) { 7 return n1 - n2; 8 }, 9 multi: function(n1, n2) { 10 return n1 * n2; 11 }, 12 div: function(n1, n2) { 13 return n1 / n2; 14 }, 15 16 } 17 console.log(per.add(10, 20)); 18 console.log(per.sbb(10, 20)); 19 console.log(per.multi(10, 20)); 20 console.log(per.div(10, 20)); 21 </script>
運行結果:
2.采用構造函數的方式,把方法加減乘除方法寫在構造函數中
1 <script> 2 function OPP(n1, n2) { 3 this.num1 = n1 || 0; // 當傳入參數n1時,設置this.num1 = n1,否則設置為0; 4 this.num2 = n2 || 0; // 當傳入參數n2時,設置this.num2 = n2,否則設置為0; 5 this.setdata = function(n1, n2) { 6 this.num1 = n1 || 0; // 當傳入參數n1時,設置this.num1 = n1,否則設置為0; 7 this.num2 = n2 || 0; // 當傳入參數n2時,設置this.num2 = n2,否則設置為0; 8 }; 9 // 函數的運行,首先設置相關元素的屬性值,然后再進行調用 10 this.add = function() { 11 // 當add()函數傳入參數時,那么設置參數就使用傳入的參數arguments[0]/arguments[1],否則使用原先的構造函數的參數this.num1/this.num2 12 this.setdata(arguments[0] || this.num1, arguments[1] || this.num2); 13 return this.num1 + this.num2; 14 }; 15 this.sbb = function() { 16 this.setdata(arguments[0] || this.num1, arguments[1] || this.num2); 17 return this.num1 - this.num2; 18 }; 19 this.multi = function() { 20 this.setdata(arguments[0] || this.num1, arguments[1] || this.num2); 21 return this.num1 * this.num2; 22 }; 23 this.div = function() { 24 this.setdata(arguments[0] || this.num1, arguments[1] || this.num2); 25 return this.num1 / this.num2; 26 } 27 } 28 console.log(new OPP(10, 20).add()); // 30 29 console.log(new OPP().add(10, 20)); // 30 30 console.log(new OPP(100, 200).add(10, 20)); //30 31 console.log(new OPP(10, 20).sbb()); //-10 32 console.log(new OPP().sbb(10, 20)); //-10 33 console.log(new OPP(100, 200).sbb(10, 20)); //-10 34 console.log(new OPP(10, 20).multi()); //200 35 console.log(new OPP().multi(10, 20)); //200 36 console.log(new OPP(10, 20).div()); //0.5 37 console.log(new OPP().div(10, 20)); //0.5 38 </script>
運行結果:
3. 采用構造函數的原型對象的方式,即將調用函數掛載到了構造函數的原型對象上,當調用函數時,是通過原型鏈進行調用的,而上一個沒有涉及到原型鏈的問題,這是與上一種方式的本質區別
1 <script> 2 function OPP(n1, n2) { 3 this.num1 = n1 || 0; // 當傳入參數n1時,設置this.num1 = n1,否則設置為0; 4 this.num2 = n2 || 0; // 當傳入參數n2時,設置this.num2 = n2,否則設置為0; 5 } 6 OPP.prototype = { 7 constructor: OPP, 8 setdata: function(n1, n2) { 9 this.num1 = n1 || 0; 10 this.num2 = n2 || 0; 11 }, 12 add: function() { 13 this.setdata(arguments[0] || this.num1, arguments[1] || this.num2); 14 return this.num1 + this.num2; 15 }, 16 sbb: function() { 17 this.setdata(arguments[0] || this.num1, arguments[1] || this.num2); 18 return this.num1 - this.num2; 19 }, 20 multi: function() { 21 this.setdata(arguments[0] || this.num1, arguments[1] || this.num2); 22 return this.num1 * this.num2; 23 }, 24 div: function() { 25 this.setdata(arguments[0] || this.num1, arguments[1] || this.num2); 26 return this.num1 / this.num2; 27 }, 28 }; 29 30 console.log(new OPP(10, 20).add()); // 30 31 console.log(new OPP().add(10, 20)); // 30 32 console.log(new OPP(100, 200).add(10, 20)); //30 33 console.log(new OPP(10, 20).sbb()); //-10 34 console.log(new OPP().sbb(10, 20)); //-10 35 console.log(new OPP(100, 200).sbb(10, 20)); //-10 36 console.log(new OPP(10, 20).multi()); //200 37 console.log(new OPP().multi(10, 20)); //200 38 console.log(new OPP(10, 20).div()); //0.5 39 console.log(new OPP().div(10, 20)); //0.5 40 </script>
運行結果:
4. 使用繼承的方式實現:
1 <script> 2 function OPP(n1, n2) { 3 this.num1 = n1 || 0; // 當傳入參數n1時,設置this.num1 = n1,否則設置為0; 4 this.num2 = n2 || 0; // 當傳入參數n2時,設置this.num2 = n2,否則設置為0; 5 }; 6 OPP.prototype.run = function() { 7 throw new Error('原型鏈中沒有該方法,請從寫該方法才能調用!'); 8 }; 9 10 function object(o) { 11 var G = function() {}; 12 G.prototype = o; 13 return new G(); 14 }; 15 16 function inheritPrototype(subObj, superObj) { 17 //調用中間函數:object,實現把子類的原型對象指向中間函數G的實例,而G的實例指向想父類的原型對象, 18 // 同時把實例的constructor 屬性指向子類;相當於在原型鏈中增加了一個實例,而實例作為子類的原型對象,這樣子類就可以通過原型鏈實現對父類的繼承了 19 var proObj = object(superObj.prototype); 20 // 調用object()函數的意義,基本上就是實現以下注釋的功能 21 // var G = function() {}; 22 // G.prototype = superObj.prototype; 23 // var proObj = new G(); 24 proObj.constructor = subObj; 25 subObj.prototype = proObj; 26 }; 27 28 function add(n1, n2) { 29 OPP.call(this, n1, n2); 30 }; 31 inheritPrototype(add, OPP); 32 add.prototype.run = function() { 33 return this.num1 + this.num2; 34 }; 35 36 function sbb(n1, n2) { 37 OPP.call(this, n1, n2); 38 }; 39 inheritPrototype(sbb, OPP); 40 sbb.prototype.run = function() { 41 return this.num1 - this.num2; 42 }; 43 44 function multi(n1, n2) { 45 OPP.call(this, n1, n2); 46 }; 47 inheritPrototype(multi, OPP); 48 multi.prototype.run = function() { 49 return this.num1 * this.num2; 50 }; 51 52 function div(n1, n2) { 53 OPP.call(this, n1, n2); 54 }; 55 inheritPrototype(div, OPP); 56 div.prototype.run = function() { 57 return this.num1 / this.num2; 58 }; 59 60 var huanying2015 = function(n1, n2, oper) { 61 switch (oper) { 62 case '+': 63 return new add(n1, n2).run(); 64 break; 65 case '-': 66 return new sbb(n1, n2).run(); 67 break; 68 case '*': 69 return new multi(n1, n2).run(); 70 break; 71 case '/': 72 return new div(n1, n2).run(); 73 break; 74 } 75 } 76 77 console.log(huanying2015(100, 200, '+')); 78 console.log(huanying2015(100, 200, '-')); 79 console.log(huanying2015(100, 200, '*')); 80 console.log(huanying2015(100, 200, '/')); 81 </script>
運行結果: