当前位置: 首页 > news >正文

哈尔滨的网站建设公司哪家好平面设计的网站

哈尔滨的网站建设公司哪家好,平面设计的网站,域客式单页网站能申请域名吗,云南住房和城乡建设厅网站首页为什么代码要整洁#xff1f; 代码质量与整洁度成正比。有的团队在赶工期的时候#xff0c;不注重代码的整洁#xff0c;代码写的越来越糟糕#xff0c;项目越来越混乱#xff0c;生产力也跟着下降#xff0c;那就必须找更多人来提高生产力#xff0c;开发成本越来越高…为什么代码要整洁 代码质量与整洁度成正比。有的团队在赶工期的时候不注重代码的整洁代码写的越来越糟糕项目越来越混乱生产力也跟着下降那就必须找更多人来提高生产力开发成本越来越高。 整洁的代码是怎样的 清晰表达意图、消除重复、简单抽象、能通过测试。 换句话说具有可读性、可重用性和可重构性。 命名 名副其实不使用缩写、不使用让人误解的名称不要让人推测。 // bad: 啥const yyyymmdstr  moment().format(YYYY/MM/DD);// bad: 缩写const cD  moment().format(YYYY/MM/DD);// good:const currentDate  moment().format(YYYY/MM/DD); const locations  [Austin, New York, San Francisco];// bad推测l是locations的项locations.forEach(l  doSomeThing(l));// goodlocations.forEach(location  doSomeThing(location)); 使用方便搜索的名称避免硬编码对数据用常量const记录。 // bad: 86400000指的是setTimeout(goToWork, 86400000);// good: 86400000是一天的毫秒数const MILLISECONDS_PER_DAY  60 * 60 * 24 * 1000;setTimeout(goToWork, MILLISECONDS_PER_DAY); 类名应该是名词方法名应该是动词。 // badfunction visble() {}// goodfunction getVisble() {} 多个变量属于同一类型的属性那就他们整合成一个对象。同时省略多余的上下文。 // bad可以整合 const carMake  Honda, const carModel  Accord, const carColor  Blue,// bad: 多余上下文 const Car  {carMake: Honda,carModel: Accord,carColor: Blue, };// good const Car  {make: Honda,model: Accord,color: Blue, }; 其他 不要写多余的废话比如theMessage的the可以删除。 统一术语。比如通知一词不要一会在叫notice一会叫announce。 用读得通顺的词语。比如getElementById就比 useIdToGetElement好读。 函数方法 删除重复的代码dont repeat yourself。很多地方可以注意dry比如偷懒复制了某段代码、try...catch或条件语句写了重复的逻辑。 // badtry {doSomeThing();clearStack();} catch (e) {handleError(e);clearStack();}// goodtry {doSomeThing();} catch (e) {handleError(e);} finally {clearStack();} 形参不超过三个对测试函数也方便。多了就使用对象参数。 同时建议使用对象解构语法有几个好处 1. 能清楚看到函数签名有哪些熟悉 2. 可以直接重新命名 3. 解构自带克隆防止副作用 4. Linter检查到函数未使用的属性。// bad function createMenu(title, body, buttonText, cancellable) {}// good function createMenu({ title, body, buttonText, cancellable }) {} 函数只做一件事代码读起来更清晰函数就能更好地组合、测试、重构。 // bad: 处理了输入框的change事件并创建文件的切片并保存相关信息到localStorage function handleInputChange(e) {const file  e.target.files[0];// --- 切片 ---const chunkList  [];let cur  0;while (cur  file.size) {chunkList.push({chunk: file.slice(cur, cur  size)});cur  size;}// --- 保存信息到localstorage ---localStorage.setItem(file, file.name);localStorage.setItem(chunkListLength, chunkList.length); }// good: 将三件事分开写同时自顶而下读很舒适 function handleInputChange(e) {const file  e.target.files[0];const chunkList  createChunk(file);saveFileInfoInLocalStorage(file, chunkList); } function createChunk(file, size  SLICE_SIZE) {const chunkList  [];let cur  0;while (cur  file.size) {chunkList.push({chunk: file.slice(cur, cur  size)});cur  size;}return chunkList } function saveFileInfoInLocalStorage(file, chunkList) {localStorage.setItem(file, file.name);localStorage.setItem(chunkListLength, chunkList.length); } 自顶向下地书写函数人们都是习惯自顶向下读代码如为了执行A需要执行B为了执行B需要执行C。如果把A、B、C混在一个函数就很难读了。(看前一个的例子)。 不使用布尔值来作为参数遇到这种情况时一定可以拆分函数。 // badfunction createFile(name, temp) {if (temp) {fs.create(./temp/${name});} else {fs.create(name);}}// goodfunction createFile(name) {fs.create(name);}function createTempFile(name) {createFile(./temp/${name});} 避免副作用。 副作用的缺点出现不可预期的异常比如用户对购物车下单后网络差而不断重试请求这时如果添加新商品到购物车就会导致新增的商品也会到下单的请求中。 集中副作用遇到不可避免的副作用时候比如读写文件、上报日志那就在一个地方集中处理副作用不要在多个函数和类处理副作用。 其它注意的地方 常见就是陷阱就是对象之间共享了状态使用了可变的数据类型比如对象和数组。对于可变的数据类型使用immutable等库来高效克隆。 避免用可变的全局变量。   // bad注意到cart是引用类型const addItemToCart  (cart, item)  {cart.push({ item, date: Date.now() });};// goodconst addItemToCart  (cart, item)  {return [...cart, { item, date: Date.now() }];}; 封装复杂的判断条件提高可读性。  // badif (!(obj  obj ! null  typeof obj[Symbol.iterator]  function)) {throw new Error(params is not iterable)}// goodconst isIterable  obj  obj ! null  typeof obj[Symbol.iterator]  function;if (!isIterable(promises)) {throw new Error(params is not iterable)} 在方法中有多条件判断时候为了提高函数的可扩展性考虑下是不是可以使用能否使用多态性来解决。  // 地图接口可能来自百度也可能来自谷歌const googleMap  {show: function (size) {console.log(开始渲染谷歌地图, size));}};const baiduMap  {render: function (size) {console.log(开始渲染百度地图, size));}};// bad: 出现多个条件分支。如果要加一个腾讯地图就又要改动renderMap函数。function renderMap(type) {const size  getSize();if (type  google) {googleMap.show(size);} else if (type  baidu) {baiduMap.render(size);}};renderMap(google)// good实现多态处理。如果要加一个腾讯地图不需要改动renderMap函数。// 细节函数作为一等对象的语言中作为参数传递也会返回不同的执行结果也是“多态性”的体现。function renderMap (renderMapFromApi) {const size  getSize();renderMapFromApi(size);}renderMap((size)  googleMap.show(size)); 其他 如果用了TS没必要做多余类型判断。 注释 一般代码要能清晰的表达意图只有遇到复杂的逻辑时才注释。 // good由于函数名已经解释不清楚函数的用途了所以注释里说明。// 在nums数组中找出 和为目标值 target 的两个整数并返回它们的数组下标。const twoSum  function(nums, target) {let map  new Map()for (let i  0; i  nums.length; i) {const item  nums[i];const index  map.get(target - item)if (index ! undefined){return [index, i]}map.set(item, i)}return []};// bad加了一堆废话const twoSum  function(nums, target) {// 声明map变量let map  new Map()// 遍历for (let i  0; i  nums.length; i) {const item  nums[i];const index  map.get(target - item)// 如果下标为空if (index ! undefined){return [index, i]}map.set(item, i)}return []};警示作用解释此处不能修改的原因。 // hack: 由于XXX历史原因只能调度一下。setTimeout(doSomething, 0) TODO注释记录下应该做但还没做的工作。另一个好处提前写好命名可以帮助后来者统一命名风格。 class Comment {// todo: 删除功能后期实现delete() {}} 没用的代码直接删除不要注释反正git提交历史记录可以找回。 // bad: 如下重写了一遍两数之和的实现方式// const twoSum  function(nums, target) {//     for(let i  0;inums.length;i){//         for(let j  i1;jnums.length;j){//             if (nums[i]  nums[j]  target) {//                 return [i,j]//             }//         }//     }// };const twoSum  function(nums, target) {let map  new Map()for (let i  0; i  nums.length; i) {const item  nums[i];const index  map.get(target - item)if (index ! undefined){return [index, i]}map.set(item, i)}return []}; 避免循规式注释不要求每个函数都要求jsdocjsdoc一般是用在公共代码上。 // bad or good?/*** param {number[]} nums* param {number} target* return {number[]}*/const twoSum  function(nums, target) {}对象 多使用getter和settergetXXX和setXXX。好处 在set时方便验证。 可以添加埋点和错误处理。 可以延时加载对象的属性。 // goodfunction makeBankAccount() {let balance  0;function getBalance() {return balance;}function setBalance(amount) {balance  amount;}return {getBalance,setBalance};}const account  makeBankAccount();account.setBalance(100); 使用私有成员。对外隐藏不必要的内容。 // badconst Employee  function(name) {this.name  name;};Employee.prototype.getName  function getName() {return this.name;};const employee  new Employee(John Doe);delete employee.name;console.log(employee.getName()); // undefined// goodfunction makeEmployee(name) {return {getName() {return name;}};} 类 solid 单一职责原则 (SRP) - 保证“每次改动只有一个修改理由”。因为如果一个类中有太多功能并且您修改了其中的一部分则很难预期改动对其他功能的影响。 // bad设置操作和验证权限放在一起了class UserSettings {constructor(user) {this.user  user;}changeSettings(settings) {if (this.verifyCredentials()) {// ...}}verifyCredentials() {// ...}}// good: 拆出验证权限的类class UserAuth {constructor(user) {this.user  user;}verifyCredentials() {// ...}}class UserSettings {constructor(user) {this.user  user;this.auth  new UserAuth(user);}changeSettings(settings) {if (this.auth.verifyCredentials()) {// ...}}} 开闭原则 (OCP) - 对扩展放开但是对修改关闭。在不更改现有代码的情况下添加新功能。比如一个方法因为有switch的语句每次出现新增条件时就要修改原来的方法。这时候不如换成多态的特性。 // bad: 注意到fetch用条件语句了不利于扩展class AjaxAdapter extends Adapter {constructor() {super();this.name  ajaxAdapter;}}class NodeAdapter extends Adapter {constructor() {super();this.name  nodeAdapter;}}class HttpRequester {constructor(adapter) {this.adapter  adapter;}fetch(url) {if (this.adapter.name  ajaxAdapter) {return makeAjaxCall(url).then(response  {// transform response and return});} else if (this.adapter.name  nodeAdapter) {return makeHttpCall(url).then(response  {// transform response and return});}}}function makeAjaxCall(url) {// request and return promise}function makeHttpCall(url) {// request and return promise}// goodclass AjaxAdapter extends Adapter {constructor() {super();this.name  ajaxAdapter;}request(url) {// request and return promise}}class NodeAdapter extends Adapter {constructor() {super();this.name  nodeAdapter;}request(url) {// request and return promise}}class HttpRequester {constructor(adapter) {this.adapter  adapter;}fetch(url) {return this.adapter.request(url).then(response  {// transform response and return});}} 里氏替换原则 (LSP) 两个定义 如果S是T的子类则T的对象可以替换为S的对象而不会破坏程序。 所有引用其父类对象方法的地方都可以透明的替换为其子类对象。 也就是保证任何父类对象出现的地方用其子类的对象来替换不会出错。下面的例子是经典的正方形、长方形例子。 // bad: 用正方形继承了长方形class Rectangle {constructor() {this.width  0;this.height  0;}setColor(color) {// ...}render(area) {// ...}setWidth(width) {this.width  width;}setHeight(height) {this.height  height;}getArea() {return this.width * this.height;}}class Square extends Rectangle {setWidth(width) {this.width  width;this.height  width;}setHeight(height) {this.width  height;this.height  height;}}function renderLargeRectangles(rectangles) {rectangles.forEach(rectangle  {rectangle.setWidth(4);rectangle.setHeight(5);const area  rectangle.getArea(); // BAD: 返回了25其实应该是20rectangle.render(area);});}const rectangles  [new Rectangle(), new Rectangle(), new Square()];// 这里替换了renderLargeRectangles(rectangles);// good: 取消正方形和长方形继承关系都继承Shapeclass Shape {setColor(color) {// ...}render(area) {// ...}}class Rectangle extends Shape {constructor(width, height) {super();this.width  width;this.height  height;}getArea() {return this.width * this.height;}}class Square extends Shape {constructor(length) {super();this.length  length;}getArea() {return this.length * this.length;}}function renderLargeShapes(shapes) {shapes.forEach(shape  {const area  shape.getArea();shape.render(area);});}const shapes  [new Rectangle(4, 5), new Rectangle(4, 5), new Square(5)];renderLargeShapes(shapes); 接口隔离原则 (ISP) - 定义是客户不应被迫使用对其而言无用的方法或功能。常见的就是让一些参数变成可选的。 // badclass Dog {constructor(options) {this.options  options;}run() {this.options.run(); // 必须传入 run 方法不然报错}}const dog  new Dog({}); // Uncaught TypeError: this.options.run is not a functiondog.run()// goodclass Dog {constructor(options) {this.options  options;}run() {if (this.options.run) {this.options.run();return;}console.log(跑步);}} 依赖倒置原则DIP - 程序要依赖于抽象接口(可以理解为入参)不要依赖于具体实现。这样可以减少耦合度。 // badclass OldReporter {report(info) {// ...}}class Message {constructor(options) {// ...// BAD: 这里依赖了一个实例那你以后要换一个就麻烦了this.reporter  new OldReporter();}share() {this.reporter.report(start share);// ...}}// goodclass Message {constructor(options) {// reporter 作为选项可以随意换了this.reporter  this.options.reporter;}share() {this.reporter.report(start share);// ...}}class NewReporter {report(info) {// ...}}new Message({ reporter: new NewReporter }); 其他 优先使用 ES2015/ES6 类而不是 ES5 普通函数。 多使用方法链。 多使用组合而不是继承。 错误处理 不要忽略捕获的错误。而要充分对错误做出反应比如console.error()到控制台提交错误日志提醒用户等操作。 不要漏了catch promise中的reject。 格式 可以使用eslint工具这里就不展开说了。 最后 接受第一次愚弄 让程序一开始就做到整洁并不是一件很容易的事情。不要强迫症一样地反复更改代码因为工期有限没那么多时间。等到下次需求更迭你发现到代码存在的问题时再改也不迟。
http://www.zqtcl.cn/news/106430/

相关文章:

  • 新吴区住房和建设交通局网站小程序商城哪家好排行榜
  • 中小学网站建站模板长春火车站咨询电话
  • c2c网站特点公司网站建设亚运村
  • 邢台wap网站建设费用黑帽seo之搜索引擎
  • 如何用阿里云做网站刷题网站怎么做
  • 织梦制作手机网站上海猎头公司名单
  • 免费生成图片的网站wordpress 购物
  • 江西建设部网站国际新闻最新消息今天2023
  • 怎么做网站啊wordpress英文显示改中文
  • 建筑专业网站有哪些网站标题seo外包优化
  • 浙江建设厅网站施工员报名中国建设协会官网站
  • 网站建设优化是干嘛上海今天最新的新闻
  • 网站大全浏览器软文的概念
  • 盐山做网站价格莱芜征婚吧
  • 具有品牌的微网站建设网站设计培训班前台
  • 网站推广工具推荐html网站地图在线生成
  • 成都本地网站建设青岛电子商务的网站建设
  • 北京网站开发培训河南省百城建设提质工程网站
  • 郑州专业建网站南通网站建设技术支持
  • 简约网站程序网络营销方式较为单一
  • 绍兴企业自助建站123房产网
  • 科技类网站设计特点备案 网站首页地址
  • 做兼职网站网站建设培训速成
  • 开源的网站管理系统商务网站设计与建设实训
  • 东莞三合一网站制作江阴做网站的公司有
  • mvc5 网站开发之學 pdf百度搜索引擎首页
  • 手机进入网站自动识别城阳区规划建设局网站
  • 网站开发平台的公司订票网站开发公司
  • 郑州网站推广信息网架结构厂家
  • 提升网站流量的方法汕头站扩建