首页 > 作文

JavaScript代码整洁之道

更新时间:2023-04-03 13:43:39 阅读: 评论:0

javascript代码整洁之道

整洁的代码不仅仅是让人看起来舒服,更重要的是遵循一些规范能够让你的代码更容易维护,同时降低bug几率。

原文clean-code-javascript,这里总结摘录出个人觉得有帮助的地方,也加入了河流地貌的发育一些自己的理解(有些文字我感觉保留原文更好,所以直接copy了),其他还有很多点没有列出来,感兴趣可以去看原文。另外这不是强制的代码规范,就像原文中说的,the are guidelines and nothing more。

1. 用命名的变量代替数组下标

// badconst address = "one infinite loop, cupertino 95014";const cityzipcoderegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;savecityzipcode(  // 下标1,2不易于理解  address.match(cityzipcoderegex)[1],  address.match(cityzipcoderegex)[2]);
// goodconst address = "one infinite loop, cupertino 95014";const cityzipcoderegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;// 使用数组解构更好的命名变量const [, city, zipcode] = address.match(cityzipcoderegex) || [];savecityzipcode(city, zipcode);

2. 函数的参数最好<=2个,尽量避免3个。

如果有很多参数就利用object传递,并使用解构。

注意object array这些引用类型的值是mutable的。

3. 一个函数只做一件事。

好处在于compo, test, and reason about。

4. 不要自行扩展原型

如果想扩展原型,可以先继承再添加方法,防止污染。

// badarray.prototype.diff = function diff(comparisonarray) {  const hash = new t(comparisonarray);  return this.filter(elem => !hash.has(elem));};
// goodclass superarray extends array {  diff(comparisonarray) {    const hash = new t(comparisonarray);    return this.filter(elem => !hash.has(elem));  }}

5. 用多态来代替条件语句

// badif (type === '婉约派代表词人text') {    // do something} el if (type === 'lect') {    // do something el}

我个人写这种代码的一种常用方式是:

const control = {    text: {        mapper() {},        restore(){},        name: 'this is a text field',    },    lect: {        mapper() {},        restore(){},        name: 'this is a lect field',    }}control[type].mapper();

实际上就是多态(polymorphism),也可以考虑用class的方式,大概这样:

class field {    ...}class textfield extends field {    mapper(){}    restore(){}    name = 'this is a text field';}class lectfield extends field {    mapper(){}    restore(){}    name = 'this is a lect field';}

6. 使用getter和tter函数。

// badfunction makebankaccount() {  // ...  return {    balance: 0    // ...  };}const account = makebankaccount();account.balance = 100;
// goodfunction makebankaccount() {  // this one is private  let balance = 0;  // a "getter", made public via the returned object below  function getbalance() {    return balance;  }  // a "tter", made public via the returned object below  function tbalance(amount) {    // ... validate before updating the balance    balance = amount;  }  return {    // ...    getbalance,    tbalance  };}const account = makebankaccount();account.tbalance(100);

你可以在getter和tter里面做很多事情而不需要修改每一个.balance的地方。

7. prefer composition over inheritance

尽量用组合来代替继承,什么情况下用继承:

your inheritance reprents an “is-a” relationship and not a “has-a” relationship (human->animal vs. ur->urdetails). you can reu code from the ba class (humans can move like all animals). you want to make global changes to derived class by changing a ba class. (change the caloric expenditure of all animals when they move).

8. solid

single responsibility principle 单一职责原则

there should never be more than one reason for a class to change,一个类被改变的原因数量应该尽可能降低。如果一个类中功能太多,当你修改其中一点时会无法估量任何引用该类的模块所受到的影响。

open/clod principle 开放封闭原则

用户可以在不修改内部实现的前提下自行扩展功能。例如有一个http模块,内部会根据环境判断用哪个adaptor。如果用户要添加adaptor就必须修改http模块。

// badclass 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(respon => {        // transform respon and return      });    } el if (this.adapter.name === "nodeadapter") {      return makehttpcall(url).then(respon => {        // transform respon and return      });    }  }}function makeajaxcall(url) {  // request and return promi}function makehttpcall(url) {  // request and return promi}
// goodclass ajaxadapter extends adapter {  constructor() {    super();    this.name = "ajaxadapter";  }  request(url) {    // request and return promi  }}class nodeadapter extends adapter {  constructor() { lol连接不上服务器   super();    this.name = "nodeadapter";  }  request(url) {    // request and return promi  }}class httprequester {  constructor(adapter) {    this.adapter = adapter;  }  fetch(url) {    return this.adapter.request(url).then(respon => {      // transform respon and return    });  }}

li时政新闻热点skov substitution principle 里式替换原则

父类和子类应该可以被交换使用而不会出错。

// badclass rectangle {  constructor() {    this.width = 0;    this.height = 0;  }  tcolor(color) {    // ...  }  render(area) {    // ...  }  twidth(width) {    this.width = width;  }  theight(height) {    this.height = height;  }  getarea() {    return this.width * this.height;  }}class square extends rectangle {  twidth(width) {    this.width = width;    this.height = width;  }  theight(height) {    this.width = height;    this.height = height;  }}function renderlargerectangles(rectangles) {  rectangles.foreach(rectangle => {    rectangle.twidth(4);    rectangle.theight(5);    const area = rectangle.getarea(); // bad: returns 25 for square. should be 20.    rectangle.render(area);  });}const rectangles = [new rectangle(), new rectangle(), new square()];renderlargerectangles(rectangles);

上面的rectangle不能直接替换square,因为会导致计算面积错误,考虑将计算面积的方法抽象出来:

class shape {  tcolor(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);

interface gregation principle 接口隔离原则

clients should not be forced to depend upon interfaces that they do not u。举例来说,一个功能模块需要设计必须传的参数和可选参数,不应该强迫用户使用可选参数。

dependency inversion principle 依赖注入原则

原文:

high-level modules should not depend on low-level modules. both should depend on abstractions. abstractions should not depend upon details. details should depend on abstractions.

// badclass inventoryrequester {  constructor() {    this.req_methods = ["http"];  }  requestitem(item) {    // ...  }}class inventorytracker {  constructor(items) {    this.items = items;    // bad: we have created a dependency on a specific request implementation.    // we should just have requestitems depend on a request method: `request`    this.requester = new inventoryrequester();  }  requestitems() {    this.items.foreach(item => {      this.requester.requestitem(item);    });  }}const inventorytracker = new inventorytracker(["apples", "bananas"]);inventorytracker.requestitems();

上面例子在于,inventorytracker内部实例化了inventoryrequester,也就意味着high-level的模块需要知道low-level模块的细节(比如实例化inventoryrequester需要知道它的构造参数等,或者说需要import该模块,造成耦合)。

// goodclass inventorytracker {  constructor(items, requester) {    this.items = items;    this.requester = requester;  }  requestitems() {    this.items.foreach(item => {      this.requester.requestitem(item);    });  }}class inventoryrequesterv1 {  constructor() {    this.req_methods = ["http"];  }  requestitem(item) {    // ...  }}class inventoryrequesterv2 {  constructor() {    this.req_methods = ["ws"];  }  requestitem(item) {    // ...  }}// by constructing our dependencies externally and injecting them, we can easily// substitute our request module for a fancy new one that us websockets.const inventorytracker = new inventorytracker(  ["apples", "bananas"],  new inventoryrequesterv2());inventorytracker.requestitems();

直接传入low-level的实例而不需要考虑它是如何被实例化的,high-level只需要依赖抽象的接口就可以完成对子模块的调用。

9. 注释

comments are an apology, not a requirement. good code mostly documents itlf. 好的代码是自解释的。

参考:clean-code-javascript

本文发布于:2023-04-03 13:43:38,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/ce99c386688bb3f4bea28ea04dae882c.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:JavaScript代码整洁之道.doc

本文 PDF 下载地址:JavaScript代码整洁之道.pdf

下一篇:返回列表
标签:模块   参数   代码   原文
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图