Nodejs代码里如何保证缩进层级不会太多

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nodejs代码里如何保证缩进层级不会太多相关的知识,希望对你有一定的参考价值。

如果是因为回调函数造成的,可以用一些类似promise的库,或者版本支持的情况下用async/await语法,或者理解能力强可以试试yield
如果是if判断造成的,可以倒置条件,然后用return来减少层级
也有do...while(false);的用法,这里面do后面的代码会至少执行一次,里面可以用break来跳过后面的代码
如果是循环层级太多的话,建议还是封装一下function吧,毕竟三层以上的循环就已经不在建议范围内了
参考技术A 少点嵌套不就少了。

Javascript 前端开发规范——阿里云

缩进层级

使用 四个空格进行缩进,以便在所有的系统和编辑器中,文件的展现格式不会有任何差异。

语句格式

始终使用分号 ;结尾一个语句。禁止省略分号,因为: 后续使用构建工具时,可以通过自动删除多余的空格和换行来压缩代码行(代码行结尾处没有分号会导致压缩错误)。 在某些情况下增进代码的性能,因为这样解析器就不必再花时间推测应该在哪里插入分号了。始终使用花括号 {}包住块语句,可以让编程意图更清晰,降低修改代码时出错的几率。 块语句使用空格间隔。

// 不好的写法,缺少空格间隔if(condition){ doSomething();}

字面量

JavaScript 中有三种基本包装类型: Boolean、 Number、 String,每种类型都代表全局作用域中的一个构造函数,并分别表示各自对应的原始值的对象。基本包装类型的主要作用是让原始值具有对象般的行为。要避免直接使用这些基本包装类型,应该直接使用对应的字面量:
由于相等( ==)和不相等( !=)操作符存在 自动类型转换的问题,因此禁止使用。为了保持代码中数据类型的完整性,要求使用全等( ===)和不全等( !==)操作符。

变量命名

变量命名使用小驼峰式(Camel Case)命名法,即以小写字母开头,后续每个单词首字母都大写。 常量命名使用大写字母和下划线。 函数变量使用前缀: fn。 函数入参使用下划线前缀: _。

DOM 变量

DOM 变量使用前缀 js-,并中缀如下:
前缀 描述
ipt input 输入框
btn 按钮
lbl Label 标签
chk CheckBox 复选框
lnk A链接
img 图片

构造函数

构造函数使用大驼峰式(Pascal Case)命名法,即以大写字母开头,后续每个单词首字母都大写。

变量声明

JavaScript 函数内声明的所有变量(但不涉及赋值)都被“提前”至函数顶部。这步操作是在代码开始运行之前、 JavaScript 引擎的“预编译”阶段进行的。
为了让源代码能够非常清晰地反映出真实的变量作用域,避免潜藏错误,规范要求始终在函数顶部使用单 var语句统一声明所有变量

// 每个变量声明都独占一行var iptUsername = $(‘input[name="username"]‘), iptPwd = $(‘input[name="pwd"]‘), btnLogin = $(‘#js-btn-login‘), fnLogin = function() {}; 

函数声明

和上述变量声明提前一样,函数声明也会被 JavaScript 引擎提前(function declaration hoisting)。因此,在代码中函数的调用可以出现在函数声明之前:
规范要求函数始终 先声明后使用。

函数表达式

更好的办法是使用 函数表达式代替函数声明:

// 好的写法var doSomeThing = function() { console.log(‘Hello world!‘);};doSomeThing();

这种情况下创建的函数叫做 匿名函数(anonymous function)(也称为 拉姆达函数),因为 function关键字后面没有标识符,其 name属性为空。与使用函数声明的区别在于,如果执行顺序颠倒,函数调用 doSomeThing()将会报错。因为函数表达式必须等到解析器执行到它所在的代码行,才会真正被解释执行:
这种匿名函数可以通过在最后加上一对圆括号 ()来 立即执行并返回一个值给变量:

// 不好的写法
var doSomeThing = function() { return ‘doSomeThing‘;}();
typeof doSomeThing === ‘string‘; // true

这种写法的问题在于,会让人误以为将一个匿名函数赋值给了这个变量。除非读完整段代码并看到最后一行的那对圆括号 (),否则你不会知道是将函数赋值给变量还是将函数的执行结果赋值给变量。这种困惑会影响代码的可读性。
为了让立即执行的函数能够被一眼看出来,可以用一对圆括号 ()将函数包起来。这样做并不会影响代码的执行结果,却能让人一眼就看出这是个立即执行的函数:

// 好的写法
var doSomeThing = (function() { return ‘doSomeThing‘;})();
typeof doSomeThing === ‘string‘; // true

零全局变量

如果你编写的是一段不会被其它脚本访问到的完全独立的脚本,可以使用一个立即执行的匿名函数来创建私有作用域。

单全局变量

最小化使用全局变量的方法之一是为你的应用创建唯一一个全局变量,并将你所有的功能代码都挂载到这个全局对象上。可以参考 JavaScript 模块模式。
模块模式
必须创建一个对象并以某些数据进行初始化,同时还要公开一些能够访问这些私有数据的方法,那么我们这个时候就可以使用模块模式了。

var singleMode = (function(){
  // 创建私有变量
  var privateNum = 112;
  // 创建私有函数
  function privateFunc(){
    // 实现自己的业务逻辑代码
  }
  // 返回一个对象包含公有方法和属性
  return {
    publicMethod1: publicMethod1,
    publicMethod2: publicMethod1
  };
})();

增强的模块模式的使用场合是:适合那些单列必须是某种类型的实例,同时还必须添加某些属性或方法对其加以增强的情况。比如如下代码:

function CustomType() {
  this.name = "tugenhua";
};
CustomType.prototype.getName = function(){
  return this.name;
}
var application = (function(){
  // 定义私有
  var privateA = "aa";
  // 定义私有函数
  function A(){};
 
  // 实例化一个对象后,返回该实例,然后为该实例增加一些公有属性和方法
  var object = new CustomType();
 
  // 添加公有属性
  object.A = "aa";
  // 添加公有方法
  object.B = function(){
    return privateA;
  }
  // 返回该对象
  return object;
})();
 

模块化-最为推崇的做法是

ECMAScript 6 可以使用最新的原生模块标准语法;

不是你的对象不要动

原生对象( Object、 Array等等); 文档对象模型(DOM)( document等等); 浏览器对象模型(BOM)( window等等); 类库的对象( $、 jQuery等等)。
对于已发布的库来说,无用的方法应该被标识位“废弃”而不是直接删掉:
解决方法

继承

基于类型的继承

var MyError = function(message) { this.message = message;};
MyError.prototype = new Error(); // 基于类型的继承,继承自原生的 

门面模式

JavaScript 的继承有一些很大的限制,就是无法继承自 DOM 或 BOM 对象。解决办法是利用门面模式为这些已存在的对象创建一个新的接口,达到二次封装的效果。
jQuery 和 YUI 的 DOM 接口都使用了门面模式。例如:

// 自定义一个 DOM 对象包装器
var DOMWrapper = function(element) { this.element = element;};
DOMWrapper.prototype = { 
    constructor: DOMWrapper, 
    addClass: function(className) { this.element.className += ‘ ‘ + className; }, 
    remove: function() { this.element.parentNode.removeChild(this.element); }
};
// 用法
var wrapper = new DOMWrapper(document.getElementById("my-div"));
// 添加一个 className
wrapper.addClass("selected");
// 删除元素
wrapper.remove(); 事件处理

解耦事件处理

事件处理常见的问题是将事件处理程序和业务逻辑紧紧耦合在一起,降低了代码的可维护性:

// 不好的写法
var handleClick = function(event) { 
    // DOM Level 2 
    event.preventDefault(); 
    event.stopPropagation(); 
    // 耦合业务逻辑 
    var popup = document.getElementById("popup");
    popup.style.left = event.clientX + "px"; 
    popup.style.top = event.clientY + "px"; 
    popup.className = "reveal";
}
document.getElementById(‘btn-action‘) .addEventListener("click", handleClick, false); 
// DOM Level 2

正确的做法应该是解耦事件处理程序和业务逻辑,提高代码的可维护性:

// 好的写法 
// 事件处理程序,唯一能接触 event 对象的函数
var handleClick = function(event) { 
    // DOM Level 2 
    event.preventDefault(); 
    event.stopPropagation(); 
    showPopup(event.clientX, event.clientY); 
},
 // 抽取业务逻辑,与事件隔离,便于重用与测试 
showPopup = function(x, y) { 
    var popup = document.getElementById("popup"); 
    popup.style.left = x + "px"; 
    popup.style.top = y + "px"; 
    popup.className = "reveal"; 
}
document.getElementById(‘btn-action‘) .addEventListener("click", handleClick, false); 
// DOM Level 2

可见,业务逻辑不应该依赖于 event对象来完成功能,原因如下


















以上是关于Nodejs代码里如何保证缩进层级不会太多的主要内容,如果未能解决你的问题,请参考以下文章

如何在docker里部署nodejs

如何在 JS 中嵌入 HTML 代码

Javascript 前端开发规范——阿里云

NodeJS 单线程 如何保证其安全,稳定性?

利用Python编写一个会员管理系统,沉迷于编程的世界里!

编程入门科普向——代码风格