写一个算法,有时候可以用简单的方法就可以写出来,但是只能针对特定的环境,如果要能够适应不同的环境,就需要对算法进行优化,在优化的过程中,你会觉得非常神奇,下面来看一个简单的四则运算的算法编写方式:
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>
运行结果: