前言本博文来自公司内部前端分享。从多个方面论述了界面设计的原则,共包括七大块。是绿竹自己的一些教训。同时也参考了一些文章,地址稍后贴上。很难做到详尽充实。如果有好的建议或错误,欢迎指正。1、界面的流畅性好的界面是流畅、易懂的。主要体现在以下几个方面:1、简单的操作一个元素的css属性。下面是原生方法:document.querySelectorAll('#id')。style.color='红色';封装后functiona(selector,color){document.querySelectorAll(selector)[0].style.color=color}a('#a','red');从几十个字母长长的一行到一个简单的函数调用,体现了api的易用性2.可读性a('#a','red')是一个很好的函数,可以帮助我们简单实用地改变一个元素,但是这里问题来了,如果第一次使用修改函数的人会一头雾水,没人会告诉他a是什么函数。开发接口的时候有必要知道一件事。人们很懒惰。从颜色赋值函数来看,虽然少写了代码,但是增加了内存开销。每次执行此操作时,都需要一个映射关系。一个——>颜色。简单的几个不要紧,但通常一套框架就有几十个甚至上百个API,映射成本的增加会让程序员小弟崩溃。我们需要的是让界面有意义,我们重写a函数:.减少内存开销我们刚才的功能也是这样的。它太长了。虽然letSomeElementChangeColor降低了映射成本,但它增加了内存成本。要知道,包括学霸在内,没有人喜欢被人叫话。获取dom的原生API也存在同样的问题。文档.getElementsByClassName;在牺牲简单性的基础上。所以我们再次改写之前的函数functionsetColor(selector,color){xxxxxxxxxxxx},减少函数名,但意义没有太大变化。使其易读、易记、易用;4.可扩展所谓可扩展,就是函数的使用像流水线一样按照写的顺序执行,形成一个执行链:document.getElementById('id').style.color='red';document.getElementById('id').style.fontSize='12px';document.getElementById('id').style.backgourdColor='粉红色';使用我们之前的方法是再次封装setFontSize和setbackgroundColor这两个函数;然后执行它们setColor('id','red');setFontSiez('id','12px');setbackgroundColor('id','粉红色');显然,这种做法并不偷懒;每个id元素每次都需要重新获取,影响性能,失败;每次需要添加新方法失败,每次调用这些方法,还是失败。接下来,我们将其改写成一个可以扩展的函数。首先将获取id的方法封装成一个对象,然后在对象的各个方法中返回该对象:functiongetElement(selector){this.style=document.querySelecotrAll(selector).style;}getElement.prototype.color=function(color){this.style.color=color;returnthis;}getElement.prototype.background=function(bg){this.style.backgroundColor=color;returnthis;}getElement.prototype.fontSize=函数(大小){this.style.fontSize=size;returnthis;}//调用varel=newgetElement('#id')el.color('red').background('pink').fontSize('12px');简单,流畅,易读我们稍后会在参数中讨论如何继续优化。所以大家更喜欢用jquery的api。虽然$符号不代表什么实际意义,但是简单的符号对我们的使用还是有好处的。它体现了以上原则,简单,易读,易记,链式书写,多参数处理。噩梦:document.getElementById('id').style.color='red';document.getElementById('id').style.fontSize='12px';document.getElementById('id').style.backgourdColor='pink';dream:$('id').css({color:'red',fontSize:'12px',backgroundColor:'pink'})2.一致性1.接口的一致性相关接口保持一致的样式,一套API的使用,如果传达出一种熟悉感和舒适感,将极大地缓解开发人员对新工具的适应性。命名这个东西:保持简短,自我描述,最重要的是保持一致“计算机科学中只有两个令人头疼的问题:缓存失效和命名问题”——PhilKarlton选择一个你喜欢的措辞,并继续使用。选择一种风格并坚持下去。Nightware:setColor,letBackGroundchangefontSizemakedisplaydream:setColor;setBackground;setFontSizeset……尽量保持代码风格和命名风格,让人读你的代码就像读同一个人写的文章一样。三、参数处理1、判断参数的类型参数的类型为你的程序提供稳定的保障//我们规定color接受字符串类型functionsetColor(color){if(typeofcolor!=='string')return;做点什么}2。使用json传参使用json传值有很多优点。它可以命名参数,忽略参数的具体位置,并赋予参数默认值。比如下面这种不好的情况:functionfn(param1,param2.....................paramN)你必须按顺序传入每个参数,否则你的方法会偏离你预期的执行。正确的方法如下。functionfn(json){//给需要的参数设置默认值vardefault=extend({param:'default',param1:'default'...},json)}这个函数代码,就算你不传随便参数进来,它会按预期运行。因为在声明的时候,你会根据具体的业务来确定参数的默认值。4.可扩展性软件设计最重要的原则之一:永远不要修改接口,只要扩展它!可扩展性也要求接口的职责单一,职责多的接口难以扩展。举个栗子://需要同时改变一个元素的字体和背景//噩梦:functionset(selector,color){document.querySelectroAll(selector).style.color=color;document.querySelectroAll(selector).style.backgroundColor=color;}//功能不可扩展修改。如果需要再次改变字体大小,只能修改这个函数,在函数后面添加改变字体大小的代码//Dreamfunctionset(selector,color){varel=document.querySelectroAll(selector);el.style.color=color;el.style.backgroundColor=color;returnel;}//需要设置字体、背景颜色和大小functionsetAgain(selector,color,px){varel=set(selector,color)el.style.fontSize=px;returnel;}以上只是简单的加色。当业务复杂,代码不是你写的时候,你还得看前面的代码再修改,这显然不符合开闭原则。修改后的函数是返回元素对象,以便下次需要更改时,再次获取返回值进行处理。2.this的使用的可扩展性还包括this的灵活使用以及call和apply方法:functionsayBonjour(){alert(this.a)}obj.a=1;obj.say=sayBonjour;obj.say();//1//orsayBonjour.call||apply(obj);//1五、错误处理1、可以使用typeof或try...catch来检测错误。typeof将强制检测对象不抛出错误,这对未定义的变量特别有用。2.抛出错误大多数开发者不想在出错时自己去寻找对应的代码。最好的办法是直接在控制台输出,告诉用户发生了什么。我们可以使用浏览器的输出api:console.log/warn/error。你也可以为你自己的程序留下一些回退:try...catch。functionerror(a){if(typeofa!=='string'){console.error('paramamustbetypeofstring')}}functionerror(){try{//somecodeexcuceteheremaybethrowwrong}catch(ex){console.wran(ex);}}6.可预测性可预测性为程序接口提供了稳健性。为了保证你的代码顺利执行,必须考虑到异常的预期情况。让我们看看不可预见代码和可预见代码之间的区别。使用前面的setColor//nighwarefunctionset(selector,color){document.getElementById(selector).style.color=color;}//dreamzepto.init=function(selector,context){vardom//如果没有给出,则返回emptyZeptocollectionif(!selector)returnzepto.Z()//优化stringselectorselseif(typeofselector=='string'){selector=selector.trim()//ifit'shtmlfragment,createnodesfromit//注意:在Chrome21和Firefox15中,DOMerror12//抛出ifthefragmentdoesn'tbeginwith
