JS简易计算器——代码优化
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了JS简易计算器——代码优化,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含9517字,纯文字阅读大概需要14分钟。
内容图文
这里用一个简易计算器的案例,来说明代码的一种优化思路和具体方法
结构和样式
先放上该项目的HTML和CSS部分
1 <! DOCTYPE html > 2 < html lang ="en" > 3 < head > 4 < meta charset ="UTF-8" > 5 < meta name ="viewport" content ="width=device-width, initial-scale=1.0" > 6 < meta http-equiv ="X-UA-Compatible" content ="ie=edge" > 7 < title >简易计算器</title> 8<style> 9 body{10 background:#777777;11}12 section{13 width:500px;height:300px;14 position:absolute;top:50%;left:50%;15 margin-top:-150px;margin-left:-250px;16 border:1px dashed black;17 font-size:20px;18}19 p{20 text-align:center;21 margin-top:50px;22}23 button{24 width:40px;height:40px;25}26</style>27</head>28<body>29<section>30<p>31<input type="text" class="input_forward" value="0">32<span class="symbol">+</span>33<input type="text" class="input_backward" value="0">34<span>=</span>35<span class="result">0</span>36</p>37<p>38<button title="add">+</button>39<button title="subtract">-</button>40<button title="multiply">×</button>41<button title="divide">÷</button>42</p>43</section>44</body>45</html>
效果图如下(关注的是实际应用效果,因此CSS样式不做太多调整):
第一步:实现计算器效果
最开始先实现效果,用最简单的思路即可(目的是先实现,先完成后完善):
①获取元素:这里大多元素都是有独立的class类名的(有些直接用标签名获取),可以直接用querySelector和querySelectorAll(button按钮)获取
②封装函数:加减乘除,通过获取的元素value,计算后改变result的值,同时改变符号位
③绑定事件:给每一个button绑定事件,在点击时执行某一函数
这里直接把结构、样式和行为分离,不在HTML标签内部添加JS事件,而是在script标签中绑定事件
JS部分的代码如下:
1 // 获取所有元素 2 var num_forward = document.querySelector(".input_forward"), 3 num_backward = document.querySelector(".input_backward"), 4 symbol = document.querySelector(".symbol"), 5 result = document.querySelector(".result"), 6 btns = document.querySelectorAll("button"); 7//封装所有函数 8function addHandler(){ 9var num1 = num_forward.value, 10 num2 = num_backward.value; 11 symbol.innerText = "+"; 12 result.innerText = +num1 + +num2;//这里是为了防止被当成字符串拼接13} 14function subtractHandler(){ 15var num1 = num_forward.value, 16 num2 = num_backward.value; 17 symbol.innerText = "-"; 18 result.innerText = num1 - num2; 19} 20function multiplyHandler(){ 21var num1 = num_forward.value, 22 num2 = num_backward.value; 23 symbol.innerText = "×"; 24 result.innerText = num1 * num2; 25} 26function divideHandler(){ 27var num1 = num_forward.value, 28 num2 = num_backward.value; 29 symbol.innerText = "÷"; 30 result.innerText = num1 / num2; 31} 32//绑定事件33 btns[0].onclick = addHandler; 34 btns[1].onclick = subtractHandler; 35 btns[2].onclick = multiplyHandler; 36 btns[3].onclick = divideHandler;
第二步:修改绑定事件的方法
经过观察得知,其中的绑定事件相当于遍历了btns里的所有元素,因此绑定事件可以用循环来改写
JS代码如下:
1 // 获取所有元素 2 var num_forward = document.querySelector(".input_forward"), 3 num_backward = document.querySelector(".input_backward"), 4 symbol = document.querySelector(".symbol"), 5 result = document.querySelector(".result"), 6 btns = document.querySelectorAll("button"); 7//封装所有函数 8function addHandler(){ 9var num1 = num_forward.value, 10 num2 = num_backward.value; 11 symbol.innerText = "+"; 12 result.innerText = +num1 + +num2;//这里是为了防止被当成字符串拼接13} 14function subtractHandler(){ 15var num1 = num_forward.value, 16 num2 = num_backward.value; 17 symbol.innerText = "-"; 18 result.innerText = num1 - num2; 19} 20function multiplyHandler(){ 21var num1 = num_forward.value, 22 num2 = num_backward.value; 23 symbol.innerText = "×"; 24 result.innerText = num1 * num2; 25} 26function divideHandler(){ 27var num1 = num_forward.value, 28 num2 = num_backward.value; 29 symbol.innerText = "÷"; 30 result.innerText = num1 / num2; 31} 32//用循环绑定事件33for(var i=0;i<btns.length;i++){ 34 btns[i].onclick = function(){ 35switch(this.title){ 36case "add": 37 addHandler(); 38break; 39case "subtract": 40 subtractHandler(); 41break; 42case "multiply": 43 multiplyHandler(); 44break; 45case "divide": 46 divideHandler(); 47break; 48 } 49 } 50 }
第三步:函数的提取和封装
进一步观察,可以发现加减乘除四个函数里都分成三个部分:
①改变符号位的符号
②计算得出结果
③把计算的结果赋值到结果区域
因此把这三部分提出来,单独封装三个通用的函数,主要是为了减少函数内部的细节暴露,便于阅读函数
该部分修改后,JS代码如下:
1 // 获取所有元素 2 var num_forward = document.querySelector(".input_forward"), 3 num_backward = document.querySelector(".input_backward"), 4 symbol = document.querySelector(".symbol"), 5 result = document.querySelector(".result"), 6 btns = document.querySelectorAll("button"); 7//封装所有函数 8//计算用的函数 9function add(num1,num2){ 10return +num1 + +num2; 11} 12function subtract(num1,num2){ 13return num1 - num2; 14} 15function multiply(num1,num2){ 16return num1 * num2; 17} 18function divide(num1,num2){ 19return num1 / num2; 20} 21//修改符号位的函数22function changeSymbol(ele){ 23 symbol.innerText = ele; 24} 25//修改输出内容的函数26function changeResult(ele){ 27 result.innerText = ele; 28} 29function addHandler(){ 30var num1 = num_forward.value, 31 num2 = num_backward.value; 32 changeSymbol("+"); 33 changeResult(add(num1,num2));//这里是为了防止被当成字符串拼接34} 35function subtractHandler(){ 36var num1 = num_forward.value, 37 num2 = num_backward.value; 38 changeSymbol("-"); 39 changeResult(subtract(num1,num2)); 40} 41function multiplyHandler(){ 42var num1 = num_forward.value, 43 num2 = num_backward.value; 44 changeSymbol("×"); 45 changeResult(multiply(num1,num2)); 46} 47function divideHandler(){ 48var num1 = num_forward.value, 49 num2 = num_backward.value; 50 changeSymbol("÷"); 51 changeResult(divide(num1,num2)); 52} 53//用循环绑定事件54for(var i=0;i<btns.length;i++){ 55 btns[i].onclick = function(){ 56switch(this.title){ 57case "add": 58 addHandler(); 59break; 60case "subtract": 61 subtractHandler(); 62break; 63case "multiply": 64 multiplyHandler(); 65break; 66case "divide": 67 divideHandler(); 68break; 69 } 70 } 71 }
第四步:变量、函数模块化
目前为止,书写的JS代码中,存有太多的全局变量以及函数,观察可以发现,所有的元素都是最外部框架的子元素,因此可以用一个对象包裹起来
同时,也可以用一个对象把功能近似的函数给包裹起来,用访问对象方法的方式来调用函数
修改后的JS代码如下:
1 // 获取所有元素 2 var section = document.querySelector("section"); 3var calculatorEles = { 4 num_forward :section.querySelector(".input_forward"), 5 num_backward:section.querySelector(".input_backward"), 6 symbol:section.querySelector(".symbol"), 7 result:section.querySelector(".result"), 8 btns:section.querySelectorAll("button") 9} 10//封装所有函数11//计算用的函数12var operation = { 13 add:function(num1,num2){ 14return +num1 + +num2; 15 }, 16 subtract:function(num1,num2){ 17return num1 - num2; 18 }, 19 multiply:function(num1,num2){ 20return num1 * num2; 21 }, 22 divide:function(num1,num2){ 23return num1 / num2; 24 } 25} 26//修改符号位的函数27function changeSymbol(ele){ 28 calculatorEles.symbol.innerText = ele; 29} 30//修改输出内容的函数31function changeResult(ele){ 32 calculatorEles.result.innerText = ele; 33} 34function addHandler(){ 35 changeSymbol("+"); 36 changeResult(operation.add(calculatorEles.num_forward.value,calculatorEles.num_backward.value));//这里是为了防止被当成字符串拼接37} 38function subtractHandler(){ 39 changeSymbol("-"); 40 changeResult(operation.subtract(calculatorEles.num_forward.value,calculatorEles.num_backward.value)); 41} 42function multiplyHandler(){ 43 changeSymbol("×"); 44 changeResult(operation.multiply(calculatorEles.num_forward.value,calculatorEles.num_backward.value)); 45} 46function divideHandler(){ 47 changeSymbol("÷"); 48 changeResult(operation.divide(calculatorEles.num_forward.value,calculatorEles.num_backward.value)); 49} 50//用循环绑定事件51for(var i=0;i<calculatorEles.btns.length;i++){ 52 calculatorEles.btns[i].onclick = function(){ 53switch(this.title){ 54case "add": 55 addHandler(); 56break; 57case "subtract": 58 subtractHandler(); 59break; 60case "multiply": 61 multiplyHandler(); 62break; 63case "divide": 64 divideHandler(); 65break; 66 } 67 } 68 }
第五步:OCP原则
OCP原则,即开放封闭原则(Open Close Principle),大致上即开放接口,封闭原有的代码(防止修改时原有代码损坏)
到目前为止的代码,尚存在以下问题:
①switch语句,一般不使用switch,因为实际开发时很可能不给源代码,增删改查时无法在原有的switch内部修改
②每个button点击时触发的函数,实际上可以提取出来,直接放到for循环中(修改符号位可以识别button中的innerText,而具体调用的函数名称也在每个button的title里体现了)
③计算方法的问题,既然可以用button的innerText来识别符号位,那也可以用button的title来识别计算方法,并调用这个方法
④添加新方法的问题,类似于①,实际开发中,很可能不会提供源码,那如果需要添加新的计算方法,是无法深入到对象内部进行添加的,因此有必要写一个接口,留给未来添加新方法用
特别注意:这里不适合直接给对象添加新属性来添加新方法,因为不知道对象内部是否已经有同名的属性
综合以上,修改完成的JS代码如下:
1 // 获取所有对象 2 var cal = document.querySelector("section"); 3var calculatorEles = { 4 input_first :cal.querySelector(".input_first"), 5 input_second:cal.querySelector(".input_second"), 6 symbol:cal.querySelector(".symbol"), 7 result:cal.querySelector(".result"), 8 btns:cal.querySelectorAll("button") 9}; 10//让元素内所有元素绑定同一事件11function each(array,fn){ 12for(var i=0;i<array.length;i++){ 13 fn(i,array[i]); 14 } 15} 16//变更符号位内容17function changeSymbol(ele){ 18 calculatorEles.symbol.innerText = ele; 19} 20//变更输出内容21function changeResult(put){ 22 calculatorEles.result.innerText = put; 23} 24//加减乘除(大函数中的小函数封装)25var operation = { 26 add:function (num1,num2){ 27return +num1 + +num2; 28 }, 29 subtract:function(num1,num2){ 30return num1 - num2; 31 }, 32 multiply:function(num1,num2){ 33return num1 * num2; 34 }, 35 divide:function(num1,num2){ 36return num1 / num2; 37 }, 38//添加一个用来添加新方法的接口39 addOperation:function(name,fn){ 40if(!this[name]){ 41this[name] = fn;//只有当前对象里不含有这个名称的方法时,才会添加方法42 } 43returnthis; 44 } 45} 46//运算函数47function operate(name,num1,num2){ 48if(!operation[name]){ 49thrownew Error("没有名为"+name+"的计算方法!"); 50 } 51 operation[name](num1,num2); 52} 53 each(calculatorEles.btns,function(index,ele){ 54 ele.onclick = function(){ 55 changeSymbol(this.innerText); 56 changeResult(operate(this.title,calculatorEles.input_first.value,calculatorEles.input_second.value)); 57 } 58 });
第六步:?
本案例还有可以继续改进的地方,例如用模块化对函数进行再次封装,添加键盘事件,对小数的计算进行改进,等等
原文:https://www.cnblogs.com/shige720/p/11440826.html
内容总结
以上是互联网集市为您收集整理的JS简易计算器——代码优化全部内容,希望文章能够帮你解决JS简易计算器——代码优化所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。