zoukankan      html  css  js  c++  java
  • js书写规范

    参考文献:https://github.com/airbnb/javascript

    1. 使用 const 与 let 代替 var (const / let)

      1.1、常量使用 const 定义,避免使用 var 定义:这样可以确保无法重新分配,这可能导致错误并难以理解代码。

    // bad
    var a = 1;
    var b = 2;
    
    // good
    const a = 1;
    const b = 2;

      1.2、使用 let 代替 var 定义变量:let是像var这样的块作用域而不是函数作用域。

    // bad
    var count = 1;
    if (true) {
      count += 1;
    }
    
    // good, use the let.
    let count = 1;
    if (true) {
      count += 1;
    }

      注意: let 和 const 都是块作用域

    2. 对象(Object)

      2.1 使用文字形式创建对象

    // bad
    const item = new Object();
    
    // good
    const item = {};

      2.2、使用对象方法的简写

    // bad
    const atom = {
      value: 1,
    
      addValue: function (value) {
        return atom.value + value;
      },
    };
    
    // good
    const atom = {
      value: 1,
    
      addValue(value) {
        return atom.value + value;
      },
    };

      2.3、使用属性速记:因为简短而具有描述性

    const lukeSkywalker = 'Luke Skywalker';
    
    // bad
    const obj = {
      lukeSkywalker: lukeSkywalker,
    };
    
    // good
    const obj = {
      lukeSkywalker,
    };

      2.4:、在对象声明的开头对速记属性进行分组。

    const anakinSkywalker = 'Anakin Skywalker';
    const lukeSkywalker = 'Luke Skywalker';
    
    // bad
    const obj = {
      episodeOne: 1,
      twoJediWalkIntoACantina: 2,
      lukeSkywalker,
      episodeThree: 3,
      mayTheFourth: 4,
      anakinSkywalker,
    };
    
    // good
    const obj = {
     // 速记属性统一放前面或者后面 lukeSkywalker, anakinSkywalker, episodeOne:
    1, twoJediWalkIntoACantina: 2, episodeThree: 3, mayTheFourth: 4, };

      2.5、仅引用无效标识符的属性:更容易阅读,因为他改善了语法突出显示的功能,并且还易于通过许多JS引擎进行优化。

    // bad
    const bad = {
      'foo': 3,
      'bar': 4,
      'data-blah': 5,
    };
    
    // good
    const good = {
      foo: 3,
      bar: 4,
      'data-blah': 5,
    };

    3. 数组(Arrays)

      3.1、应尽量使用文字语法创建数组(如果有必要,特殊情况除外,如:new Array(10).fill(true))

    // bad
    const items = new Array();
    
    // good
    const items = [];

      3.2、使用 spread(‘...’)操作符copy数组

    // bad
    const len = items.length;
    const itemsCopy = [];
    let i;
    
    for (i = 0; i < len; i += 1) {
      itemsCopy[i] = items[i];
    }
    
    // good
    const itemsCopy = [...items];

      3.3、使用 spreads(‘...’)操作符将可迭代的对象转化为数组,而不是使用 Array.from([])

    const foo = document.querySelectorAll('.foo');
    
    // good
    const nodes = Array.from(foo);
    
    // best
    const nodes = [...foo];

      3.4、Array.from 用于将类似数组的对象转换为数组

    const arrLike = { 0: 'foo', 1: 'bar', 2: 'baz', length: 3 };
    
    // bad
    const arr = Array.prototype.slice.call(arrLike);
    
    // good
    const arr = Array.from(arrLike);

      3.5、使用 Array.from 而不是spread ...来映射可迭代对象,因为它避免了创建中间数组。

    // bad
    const baz = [...foo].map(bar);
    
    // good
    const baz = Array.from(foo, bar);

      3.6、如果数组有多行,则在打开和关闭数组括号之前使用换行符(因为一行的宽度是有限的,而数列的高度是无限的,这样有利于代码的阅读)

    // bad
    const arr = [
      [0, 1], [2, 3], [4, 5],
    ];
    
    const objectInArray = [{
      id: 1,
    }, {
      id: 2,
    }];
    
    const numberInArray = [
      1, 2,
    ];
    
    // good
    const arr = [[0, 1], [2, 3], [4, 5]];
    
    const objectInArray = [
      {
        id: 1,
      },
      {
        id: 2,
      },
    ];
    
    const numberInArray = [
      1,
      2,
    ];

        3.7、在数组方法回调中使用return语句。如果函数主体由一个返回单一的表达式的语句组成,则可以省略 return

    // good
    [1, 2, 3].map((x) => {
      const y = x + 1;
      return x * y;
    });
    
    // good
    [1, 2, 3].map((x) => x + 1);
    
    inbox.filter((msg) => {
      const { subject, author } = msg;
      if (subject === 'Mockingbird') {
        return author === 'Harper Lee';
      } else {
        return false;
      }
    });
    
    // good
    inbox.filter((msg) => {
      const { subject, author } = msg;
      if (subject === 'Mockingbird') {
        return author === 'Harper Lee';
      }
    
      return false;
    });

     4. 结构

      4.1、访问和使用对象的多个属性时,请使用对象分解:解构可避免您为这些属性创建临时引用,打包时能够优化代码

    // bad
    function getFullName(user) {
      const firstName = user.firstName;
      const lastName = user.lastName;
    
      return `${firstName} ${lastName}`;
    }
    
    // good
    function getFullName(user) {
      const { firstName, lastName } = user;
      return `${firstName} ${lastName}`;
    }
    
    // best
    function getFullName({ firstName, lastName }) {
      return `${firstName} ${lastName}`;
    }

       4.2、使用数组解构

    const arr = [1, 2, 3, 4];
    
    // bad
    const first = arr[0];
    const second = arr[1];
    
    // good
    const [first, second] = arr;

      4.3、对多个返回值对象解构时应当使用对象,而不是数组

    // bad
    function processInput(input) {
      // then a miracle occurs
      return [left, right, top, bottom];
    }
    
    // 调用者需要按照顺序调用
    const [left, __, top] = processInput(input);
    
    // good
    function processInput(input) {
      // then a miracle occurs
      return { left, right, top, bottom };
    }
    
    // 调用者可以选择需要的数据
    const { left, top } = processInput(input);

    5.  字符串处理

      5.1、字符串应当使用单引号 

    // bad
    const name = "Capt. Janeway";
    
    // bad - 模板字符串中应当包含插值
    const name = `Capt. Janeway`;
    
    // good
    const name = 'Capt. Janeway';

      5.2、字符串不应使用字符串连接跨多行写入:字符串损坏很难使用,并且使代码的可搜索性降低。

    // bad
    const errorMessage = 'This is a super long error that was thrown because 
    of Batman. When you stop to think about how Batman had anything to do 
    with this, you would get nowhere 
    fast.';
    
    // bad
    const errorMessage = 'This is a super long error that was thrown because ' +
      'of Batman. When you stop to think about how Batman had anything to do ' +
      'with this, you would get nowhere fast.';
    
    // good
    const errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.';

      5.3、代码构建字符串时,应当使用模板字符串,而不是使用 '+'连接符:模板字符语法更精简易懂并有适当的换行和插值功能

    const str1 = '123'
    const str2 = '234'
    // bad
    const newStr = str1 + str2
    
    //good
    const newStr = `${str1}${str2}`

      5.4、在不必要的情况下,不要使用转义字符与eval()方法

    6. 方法(Function)

      6.1、使用命名函数表达式而不是函数声明:这样更利于进行模块化开发

    // bad
    function foo() {
      // ...
    }
    
    // bad
    const foo = function () {
      // ...
    };
    
    // good
    // lexical name distinguished from the variable-referenced invocation(s)
    const short = function longUniqueMoreDescriptiveLexicalFoo() {
      // ...
    };

      6.2、不要在非功能块(如:while、if 等)中声明方法

      6.3、永远不要使用 arguments 作为函数参数,或者通过arguments的获取参数

    // bad
    function concatenateAll() {
    // 把调用方法的参数截取出来 const args
    = Array.prototype.slice.call(arguments); return args.join(''); } // good function concatenateAll(...args) { return args.join(''); }

      6.4、使用默认参数语法,而不是对函数参数进行修正,并且应当将函数的默认值参数放在函数的最后

    // really bad
    function handleThings(opts) {
      // 我们不能修改函数的参数
      // 如果 opts = false,那么则有可能变为 {}
      // 这样做可能出现一些问题
      opts = opts || {};
      // ...
    }
    
    // still bad
    function handleThings(opts) {
      if (opts === void 0) {
        opts = {};
      }
      // ...
    }
    
    // good  因为opts为默认值参数,应放在函数参数的最后
    function handleThings(id, opts = {}) {
      // ...
    }

      6.5、不应该对函数的参数进行处理,这样将难以理解

    var b = 1;
    // bad
    function count(a = b++) {
      console.log(a);
    }
    count();  // 1
    count();  // 2
    

      6.7、不要更改和重新分配函数的参数值,若需要,应当建立副本进行变更,否则将可能出现错误

      6.8、最好使用点差运算符...来调用可变参数函数。这样代码更干净

    // bad
    const x = [1, 2, 3, 4, 5];
    console.log.apply(console, x);
    
    // good
    const x = [1, 2, 3, 4, 5];
    console.log(...x);

      6.9、若有多行或函数参数有多个时应当提行

    // bad
    function foo(bar,
                 baz,
                 quux) {
      // ...
    }
    
    // good
    function foo(
      bar,
      baz,
      quux,
    ) {
      // ...
    }
    
    // bad
    console.log(foo,
      bar,
      baz);
    
    // good
    console.log(
      foo,
      bar,
      baz,
    );

    7. 箭头函数

      7.1、当您必须使用匿名函数时(如传递内联回调时),请使用箭头函数符号。

      7.2、使用匿名函数时,及时只有一个参数,也应当使用 ( )  将参数括起来

      7.3、如果函数主体由单个语句组成时,请省略花括号并使用隐式返回。否则,请保留括号并使用return语句

    // bad(匿名函数使用箭头函数)
    [1, 2, 3].filter((item) => { return item === 1 || item === 2 })
    
    // good  表达式有多行时应当换行
    [1, 2, 3].filter((item) => (
    item === 2 ||
    item === 1
    ))

    8.  js类与构造函数参考原文献

    9. 模块

      9.1、使用 improt / export 导出和导入模块:模块就是未来

    // bad
    const AirbnbStyleGuide = require('./AirbnbStyleGuide');
    module.exports = AirbnbStyleGuide.es6;
    
    // ok
    import AirbnbStyleGuide from './AirbnbStyleGuide';
    export default AirbnbStyleGuide.es6;
    
    // best
    import { es6 } from './AirbnbStyleGuide';
    export default es6;

      9.2、不要使用 * as xxx 并且不要在导入中导出 这样可以保证有单一的导出

    // bad
    import * as AirbnbStyleGuide from './AirbnbStyleGuide';
    
    // good
    import AirbnbStyleGuide from './AirbnbStyleGuide';
    // bad
    // filename es6.js
    export { es6 as default } from './AirbnbStyleGuide';
    
    // good
    // filename es6.js
    import { es6 } from './AirbnbStyleGuide';
    export default es6;

      9.3、仅从一个位置的路径导入。

    // bad
    import foo from 'foo';
    // … some other imports … //
    import { named1, named2 } from 'foo';
    
    // good
    import foo, { named1, named2 } from 'foo';
    
    // good
    import foo, {
      named1,
      named2,
    } from 'foo';

      9.4、通常只应该导出常量(也就是 const 定义的常量)

      9.5、如果一个模块只有单一的导出,应当首选 exprot default  {}, 而不是 export const foo = {}

      9.6、应该将所有的导出放置文件最顶部

      9.7、多行导入应当换行,每行只显示一个导入

    // bad
    import {longNameA, longNameB, longNameC, longNameD, longNameE} from 'path';
    
    // good
    import {
      longNameA,
      longNameB,
      longNameC,
      longNameD,
      longNameE,
    } from 'path';

    10. 属性

      10.1、访问属性时,在非必要(比如 变量 访问属性时)的情况下应使用点符号

    const luke = {
      jedi: true,
      age: 28,
    };
    
    // bad
    const isJedi = luke['jedi'];
    
    // good
    const isJedi = luke.jedi;

    11. 变量 与 常量(let 与 const)

      11.1、始终使用const或let来声明变量,不这样做将导致全局变量,污染全局名称空间

    // bad
    superPower = new SuperPower();
    
    // good
    const superPower = new SuperPower();

      11.2、 对每个变量或赋值使用一个const或let声明。

    // bad
    const items = getItems(),
        goSportsTeam = true,
        dragonball = 'z';
    
    // bad
    // (compare to above, and try to spot the mistake)
    const items = getItems(),
        goSportsTeam = true;
        dragonball = 'z';
    
    // good
    const items = getItems();
    const goSportsTeam = true;
    const dragonball = 'z';

      11.3、对所有const进行分组,然后对所有let进行分组。(统一将 const 放在 let 的前面)

      11.4、在需要它们的地方分配变量,但是将它们放在合理的位置。

    // bad - unnecessary function call
    function checkName(hasName) {
      const name = getName();
    
      if (hasName === 'test') {
        return false;
      }
    
      if (name === 'test') {
        this.setName('');
        return false;
      }
    
      return name;
    }
    
    // good
    function checkName(hasName) {
      if (hasName === 'test') {
        return false;
      }
    
      const name = getName();
    
      if (name === 'test') {
        this.setName('');
        return false;
      }
    
      return name;
    }

      11.5、不要链接变量分配:链接变量分配会创建隐式全局变量。

    // bad
    let a = b = c = 1;
    
    // good
      let a = 1;
      let b = a;
      let c = a;

      11.6、避免使用 ++ 或 --,使用 += 或 -= 代替(eslint规范)

      11.7、在 = 后边应避免换行,若需要请使用 ( ) 将内容括起来

      11.8、全局常量应当全部大写

    12. 运算符

      12.1、 == 与 != 应使用  === 与 !== 替代

      12.2、注意 if 判断,因遵循如下规则

        · object 为 true

        · undefined的结果为false

        · Null 的结果为 false

        · Booleans 的结果为 boolean值

        · Numbers +0, -0,NaN 为false,否则为true

        · 如果为空字符串“”,则字符串的计算结果为false,否则为true

    13、块

      13.1、将括号与所有多行块一起使用。

    // bad
    if (test)
      return false;
    
    // good
    if (test) return false;
    
    // good
    if (test) {
      return false;
    }
    
    // bad
    function foo() { return false; }
    
    // good
    function bar() {
      return false;
    }

      13.2、如果您将多行代码块与if和else一起使用,请将else与if块的右括号放在同一行。

    // bad
    if (test) {
      thing1();
    }
    else {
      thing3();
    }
    
    // good
    if (test) {
      thing1();
    } else {
      thing3();
    }

      13.3、如果if块始终执行return语句,则随后的else块是不必要的。

    // bad
    function foo() {
      if (x) {
        return x;
      } else {
        return y;
      }
    }
    
    // good
    function foo() {
      if (x) {
        return x;
      }
    return y; }

    14. 空格(具体遵循eslint规范)

      14.1、始终使用 2 个空格作为块之间的间距

      14.2、在前括号【{ }, ( )】之前放置1个空格

    // bad
    function test(){
      console.log('test');
    }
    
    // good
    function test() {
      console.log('test');
    }

      14.3、在控制语句中的左括号前放置1个空格(如果,则等)。在函数调用和声明中,参数列表和函数名称之间不能留空格。

    // bad
    if(isJedi) {
      fight ();
    }
    
    // good
    if (isJedi) {
      fight();
    }
    
    // bad
    function fight () {
      console.log ('Swooosh!');
    }
    
    // good
    function fight() {
      console.log('Swooosh!');
    }

      14.4、 用空格隔开运算符。

    // bad
    const sum=1+23+5
    
    // gold
    const sum = 1 + 2 +5

      14.5、 在块之后和下一条语句之前保留空白行。// bad

    const arr = [
      function foo() {
      },
      function bar() {
      },
    ];
    return arr;
    
    // good
    const arr = [
    function foo() { }, function bar() { }, ]; return arr;

      14.6、不要在括号内添加空格,不要在方括号内添加空格

    // bad
    function bar( foo ) {
      return foo;
    }
    
    // good
    function bar(foo) {
      return foo;
    }

    // bad
    const foo = [ 1, 2, 3 ];
    console.log(foo[ 0 ]);
    
    // good
    const foo = [1, 2, 3];
    console.log(foo[0]);
     

      14.7、在花括号内添加空格。

    // bad
    const foo = {clark: 'kent'};
    
    // good
    const foo = { clark: 'kent' };

      

    语句后边的分号、逗号遵循 eslint(常用通用配置:standard) 即可

  • 相关阅读:
    java-以月为单位,得到一年中某一个月份的范围
    计算两个时间段相差几个月(包含相差的哪些月份)
    单个进程最大线程数
    Dell PowerEdge R720内存安装原则
    Java [parms/options] range -b 100 -c 10 -i 100 -t 300 -s 180
    PhysicalDrive
    classpath和环境变量设置
    MySQL正则表达式
    MySQL模式匹配(LIKE VS REGEXP)
    ubuntu为什么没有/etc/inittab文件? 深究ubuntu的启动流程分析
  • 原文地址:https://www.cnblogs.com/jingxuan-li/p/12343922.html
Copyright © 2011-2022 走看看