CcbeanBlog CcbeanBlog
首页
  • 前端文章

    • JavaScript
    • HTML+CSS
    • Vue
    • React
  • 系列笔记

    • React使用学习
    • Vue2源码探究
  • Node文章

    • 基础
    • 问题
    • 框架
  • 系列笔记

    • 数据结构与算法
  • 构建工具文章

    • webpack
  • 系列笔记

    • Webpack5使用学习
  • MySQL
  • Linux
  • 网络
  • 小技巧
  • 杂记
  • 系列笔记

    • Protobuf Buffers
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Ccbean

靡不有初,鲜克有终
首页
  • 前端文章

    • JavaScript
    • HTML+CSS
    • Vue
    • React
  • 系列笔记

    • React使用学习
    • Vue2源码探究
  • Node文章

    • 基础
    • 问题
    • 框架
  • 系列笔记

    • 数据结构与算法
  • 构建工具文章

    • webpack
  • 系列笔记

    • Webpack5使用学习
  • MySQL
  • Linux
  • 网络
  • 小技巧
  • 杂记
  • 系列笔记

    • Protobuf Buffers
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 基础

    • NodeJS代码规范
      • Node的简介与模块机制
      • Node实现图片上传
      • 事件循环
      • 异步编程
    • 问题

    • 框架

    • 系列笔记

    • Node
    • 基础
    ccbean
    2021-06-22
    目录

    NodeJS代码规范

    # NodeJS代码规范

    https://github.com/dead-horse/node-style-guide

    # 2空格缩进

    使用2个空格而不是tab来进行代码缩进,同时绝对不要混用空格和tab。

    Sublime Text2设置(Preferebces > Settings > User)

    "tab_size":2,
    "translate_tabs_to_spaces": true
    

    # 换行

    使用UNIX风格的换行符(\n),同时在每个文件的结尾添加一个换行符。Windows风格的换行符(\r\n)是绝对禁止出现在任何项目中的。

    Sublime Text2设置(Preferebces > Settings > User)

    "default_line_ending": "unix"
    

    # 去除行末尾的多余空格

    就像吃完饭要刷牙一样,在提交(commit)代码之前你需要清理掉所有的不必要的空格。

    Sublime Text2设置(Preferebces > Settings > User)

    "trim_trailing_white_space_on_save": true
    

    # 使用分号

    是否使用分号,在社区争论已久,Isaac也写过一篇讨论的文章 (opens new window),但是,当可以用廉价的语法来消除一些可能引入错误的时候,请当一个保守派。

    # 每行80个字符

    限制你每行代码不超过80个字符。尽管现在的显示器越来越大,但是你的大脑并没有变大,并且你还可以把你的大显示器切分成多屏来显示。

    Sublime Text2设置(Preferebces > Settings > User)

    "rulers": [80]
    

    多屏:view > Layout > Columns 2

    # 使用单引号

    除非编写.json文件,其他时候都请用单引号包裹字符串。

    Right

    var foo = 'bar';
    

    Wrong

    var foo = "bar";
    

    # 大括号位置

    请把你的所有的左大括号都放在语句开始的这一行。

    Right

    if (true) {
      console.log('winning');
    }
    

    Wrong

    if (true)
    {
    	console.log('losing');    
    }
    

    同时,请注意在条件判断前后都添加一个空格。

    # 每个变量声明都带一个var (旧)

    每个变量声明都带一个var,这样删除或者调整变量声明的顺序会更加容易。不要把变量都生命在最前面,而是声明在它最有意义的地方。

    Right

    var keys = ['foo', 'bar'];
    var values = [23, 42];
    
    var object = {};
    while (items.length) {
      
    }
    

    Wrong

    keys = ['foo', 'bar'];
    values = [23, 42];
    
    object = {};
    while (items.length) {
      
    }
    

    # 变量、属性和函数名都采用小驼峰

    变量、属性和函数的命名风格都需要遵循小驼峰风格。 同时所有的命名都是有意义的。 尽量避免用单字符变量和少见单词来命名。Right

    var adminUser = db.query('SELECT * FROM users ...');
    

    Wrong

    var admin_user = db.query('SELECT * FROM users ...');
    var a = db.query('SELECT * FROM users ...');
    

    # 类名采用大驼峰

    类名都采用大驼峰风格来命名。

    Right

    function BankAccount() {
    }
    

    Wrong

    function bank_Account () {
    }
    

    # 用大写来标识常量

    常量变量和对象的静态常量属性都需要特殊表明,通过全部大写的方式来表明。

    尽管Node.js/V8支持mozilla的const关键字,但不幸的是,对象的属性并不支持这个关键字,而且const没有包含于任何一个ECMA规范中(现在包含了)。

    Right

    var SECOND = 1 * 1000;
    
    function File() {
    }
    File.FULL_PERMISSIONS = 0777;
    

    Wrong

    var SECOND = 1 * 1000;
    
    function File() {
    }
    File.fullPermissions = 0777;
    

    # 对象、数组的创建

    使用尾随逗号,尽量用一行来声明,只有在编译器不接受的情况下才把对象的key用单引号包裹。使用字面表达式,用{}, []代替new Object new Array

    Right

    var a = ['hello', 'world'];
    var b = {
      good: 'code',
      'is generally': 'pretty'
    };
    

    Wrong

    var a = [
      'hello', 'world'
    ];
    var b = {"good": 'code'
      			, is generally: 'pretty'
    				};
    

    # 使用 === 比较符

    使用===操作符来进行比较,它会完全按照你的期望来执行。

    Right

    var a = 0;
    if (a === '') {
      console.log('winning');
    }
    

    Wrong

    var a = 0;
    if (a == '') {
      console.log('losing');
    }
    

    # 三元操作符分多行

    三元操作符不应该写在一行,将它分割到多行。

    Right

    var foo = (a === b)
    	? 1
    	: 2;
    

    Wrong

    var foo = (a === b) ? 1 : 2;
    

    # 不要扩展内建类型

    不要扩展Javascript内建对象的方法。将来来你会感激你这个做法的。

    Right

    var a = [];
    if (!a.length) {
      console.log('winning');
    }
    

    Wrong

    Array.prototype.empty = function () {
      return !this.length;
    }
    var a = [];
    if (a.empty()) {
      console.log('losing');
    }
    

    # 使用有意义的判断条件

    所有复杂的条件判断都需要赋予一个有意义的名字或者方法。

    Right

    var isValidPassword = password.length >= 4 && /^(?=.*\d).{4,}$/.test(password);
    if (isValidPassword) {
    	console.log('winning');
    }
    

    Wrong

    if (password.length >= 4 && /^(?=.*\d).{4,}$/.test(password)) {
      console.log('losing');
    }
    

    # 尽早的从函数中返回

    为了避免深入嵌套的if语句,请尽早的从函数中返回。

    Right

    function isPercentage(val) {
      if (val < 0) {
        return false;
      }
      
      if (val > 100) {
        return false;
      }
      
      return true;
    }
    

    Wrong

    function isPercentage(val) {
      if (val >= 0) {
        if (val < 100) {
          return true;
        } else {
          return false;
        }
      } else {
        return false;
      }
    }
    

    针对这个示例,甚至可以进一步精简优化:

    function isPercentage(val) {
      var isInRange = (val >= 0 && val <= 100);
      return isInRange;
    }
    

    # 给你的闭包命名

    请尽量给你的闭包、匿名函数命名。这让人知道你在意这个函数,更重要的是,这将会产生可读性更好的堆栈。

    举例好像不适用于现在

    Right

    req.on('end', function onEnd() {
      console.log('winning')
    });
    

    Wrong

    req.on('end', function () {
      console.log('winning')
    });
    

    # 不要嵌套闭包

    使用闭包,但是不要嵌套它们,否则你的代码将会一团糟。

    Right

    setTimeout(function() {
      client.connect(afterConnect);
    }, 1000);
    function afterConnect() {
      console.log('winning');
    }
    

    Wrong

    setTimeout(function () {
      client.connect(function () {
        console.log("losing");
      });
    }, 1000);
    

    # 使用单行注释风格

    不管是单行注释还是多行注释,都是用//。同时,请尝试在更高层次来编写注释(解释函数的整体思路),只在解释一些难以理解代码的时候添加注释,而不是给一些琐碎的东西加上注释。

    Right

    // 'ID_SOMETHING' = VALUE' -> ['ID_SOMETHING', 'SOMETHING', 'VALUE']
    var matches = item.match(/ID_([^\n]+)=([^\n]+)/);
    
    // This function has a nasty side effect where a failure to increment a 
    // redis counter used for statistics will cause an exception. This needs 
    // to be fixed in a later iteration
    function loadUser(id, cb) {
      // ...
    }
    var isSessionValid = (session.expires < Date.now());
    if (isSessionValid) {
      // ...
    }
    

    Wrong

    // Execute a regex
    var matches = item.match(/ID_([^\n]+)=([^\n]+)/);
    
    // Usage: loadUsers(5, function () { ... })
    function loadUser(id, cb) {
      // ...
    }
    
    // Check if the session is valid
    var isSessionValid = (session.expires < Date.now());
    if (isSessionValid) {
      // ...
    }
    

    # Object.freeze, Object.preventExtensions, Object.seal, with, eval

    这一堆屎一样的东西,你永远不会需要他们。

    # Getters和setters

    不要使用setters,它们会引发一些使用你的代码的人无法解决的问题。当没有副作用的时候,可以使用getters,例如提供一个集合类的长度属性的时候。

    # 异步回调函数

    Node的异步回调函数的第一个参数应该是错误指示,只有这样才能享受许多流程控制模块的福利。

    Right

    function cb(err, data, ...) {...}	
    

    Wrong

    function cb(data, ...) {...}
    

    # 继承

    尽管有很多的方法来实现继承,但是最为推荐的是Node的标准写法。

    function Socket(options) {
      // ...
      stream.Stream.call(this);
      // ...
    }
    util.inherits(Socket, stream.Stream);
    

    # 文件命名

    单词之间使用_underscore来分割,如果你不想暴露某个文件给用户,可以使用_来开头

    Right

    child_process.js
    string_decoder.js
    _linklist.js
    

    Wrong

    childProcess.js
    stringDecoder.js
    

    # 空格

    在所有的操作符前后都添加空格,function关键字后面添加空格。

    Right

    var add = function (a, b) {
      return a + b;
    };
    

    Wrong

    var add=function(a,b){
      return a+b;
    }
    
    编辑 (opens new window)
    上次更新: 2021/11/10, 12:11:50
    Node的简介与模块机制

    Node的简介与模块机制→

    最近更新
    01
    阅读精通正则表达式总结
    09-29
    02
    项目搭建规范的配置
    07-15
    03
    Vite的使用
    07-03
    更多文章>
    Theme by Vdoing | Copyright © 2018-2023 Ccbeango
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式