前端项目规范

因为项目用的vue.js框架和ES6语法,所以这套规范主要出于我们自己项目来考虑的,额,有一些太基础的也就不写了,大家都懂得,哈哈。
还有一点,因为我们用了 .vue文件 ,想使用 ESlint 的话,我没有找到很好的针对 ESlint 配置的格式化插件, 所以只能手动写好代码,好纠结啊。

Javascript规范


变量声明
  • 1.1 使用 const 声明常量。
  • 1.2 使用 let 来进行变量声明,如不指定 let
    ,变量将被隐式地声明为全局变量如果没有声明,变量处于什么定义域就变得不清。不使用 var

因为 let是 block scoped 不是functional scoped,懂?var则是functional scoped。另外 const 也是 block scoped。

  //bad
  let x = 10;
  let y = 100;
  //good
  let x = 10,
      y = 100;

对象

  • 2.1 使用对象字面量来创建对象
  //bad
  const item = new Object();
  //good
  const item = {};
  • 2.2 当对象的属性需要动态生成时使用计算属性

因为这样可以让你将所有的属性在一个对象的 “同一个” 地方定义

function getKey(k){
  return `${k}`;
}
//bad
const person = {
  name: 'Helen',
  age: 18
};
person[getKey('beautiful')] = true;
//good
const person = {
  name: 'Helen',
  age: 18,
  [getKey('beautiful')]: true
}
  • 2.3 使用对象属性值的shorthand
  const data = 'test';
  //bad
  const obj = {
    data: data
  };
//good
const obj = {
    data
};
  • 2.4 将使用shorthand的属性放在对象声明的开头
  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 在 invalid 的标识符上用引号
  // bad
  const bad = { 
    'foo': 3, 
    'bar': 4, 
    'data-blah': 5,
  };
// good
  const good = { 
    foo: 3, 
    bar: 4, 
    'data-blah': 5,
};
  • 2.6 不要直接用 Object.prototype上的方法,比如:hasOwnProperty, propertyIsEnumerable, isPrototypeOf。

因为这些属性会被对象上的属性覆盖,比如:{ hasOwnProperty: false } 或者对象是一个nullObject.create(null)

  //bad
  console.log(Object.hasOwnProperty(key));
  //good
  console.log(Object.prototype.hasOwnProperty.call(obj, key));
  //best
  const has = Object.prototype.hasOwnProterty;
  import has from 'has';
  console.log(has.call(obj, key));
  • 2.7 使用 'object spread operator' ,不使用 object.assign
  //very bad
  const original = {a: 1, b: 2};
  const copy = Object.assign(original, {c: 3}); //这样会改变original ಠ_ಠ

  //bad
  const original = {a: 1, b:2};
  const copy = Object.assign({}, original, {c: 3}); // copy => { a: 1, b: 2, c: 3 }

  //good
  const original = {a: 1, b: 2};
  const copy = { ...original, {c: 3}}; //copy => { a: 1, b: 2, c: 3 }

  const {a, ...test} = copy; // test => { b: 2, c: 3 }
  • 2.8 对象设置默认属性时用Object.assign
  //bad
  const menuConfig = {
    title: null,
    body: 'Bar',
    buttonText: null,
    cancellable: true
  };
  function createMenu(config) {
  config.title = config.title || 'Foo';
  config.body = config.body || 'Bar';
  config.buttonText = config.buttonText || 'Baz';
  config.cancellable = config.cancellable === undefined ?           config.cancellable : true;
}
createMenu(menuConfig);
//good
const menuConfig = {
  title: 'Order',
  // User did not include 'body' key
  buttonText: 'Send',
  cancellable: true
};
function createMenu(config) {
    config = Object.assign({
    title: 'Foo',
    body: 'Bar',
    buttonText: 'Baz',
    cancellable: true
  }, config);

  // config now equals: {title: "Order", body: "Bar", buttonText: "Send", cancellable: true}
  // ...
}
createMenu(menuConfig);

数组

  • 3.1 使用字面量创建数组
  //bad
  const items = new Array();
  //good 
  const items = []; 
  • 3.2 使用扩展符来 copy 数组
  //bad
  const len = items.length;
  const itemsCopy = [];
  let i;
  for (i = 0; i < len; i += 1) { 
    itemsCopy[i] = items[i];
  }
//good
const itemCopy = [...items];

字符串

  • 4.1 一般字符使用单引号'',如有变量要拼的字符,使用ES6的模板字符
  let name = 'Helen';
  str = `Hello ${name}`;
  • 4.2 如果变量字符串超过100个字符,不应该写为多行
  // 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.';
  • 4.3 如果是程序构造的字符串,用 'template strings' 替换字符串拼接
  // bad
function sayHi(name) { 
    return 'How are you, ' + name + '?';
}
// good
function sayHi(name) { 
    return `How are you, ${name}?`;
}

函数

  • 5.1 给函数参数一个默认值,不在函数中判断参数
  //bad
  function handleThings(opts){
    opts = opts || {};
  }
  //good
   function handleThings(opts = {}){

    }
  • 5.2 将默认参数放在最后
  // bad
  function handleThings(opts = {}, name) { 
    // ...
  }
// good
  function handleThings(name, opts = {}) { 
    // ...
  }
  • 5.3 使用‘spread operator’ ...
  // bad
  new (Function.prototype.bind.apply(Date, [null, 2016, 08, 05]));
// good
  new Date(...[2016, 08, 05]);
  • 5.4 格式上的问题
  // bad
  function foo(bar, 
               baz, 
               quux) { 
                  // body
               }
  // good
  function foo( 
              bar,
              baz, 
              quux
              ) { 
            // body
              }
// bad
console.log(foo, 
              bar, 
              baz);
// good
console.log( 
          foo, 
          bar, 
          baz,
      );
  • 5.5 函数参数(最多两个参数)
  //bad
  function createMenu(title, body, buttonText, cancellable){
    //....
  }
  //good
  function createMenu({ title, body, buttonText, cancellable}){
    //...
  }
  createMenu({
    title: 'Foo',
    body: 'Bar',
    buttonText: 'Baz',
    cancellable: true
  })
  • 5.6 不要用flags作为函数参数
    Flags会告诉用户这个函数不止做一件事,但是函数应该只做一件事,所以,应该分离你的函数。
  //bad
  function createFile(name, temp) {
    if (temp) {
      fs.create(`./temp/${name}`);
    } else {
      fs.create(name);
    }
  }
//good
function createFile(name) {
    fs.create(name);
}
function createTempFile(name) {
    createFile(`./temp/${name}`);
}

Arrow Functions

  • 6.1 当要使用函数表达式时,使用箭头函数

使用箭头函数更加简明
但是当函数逻辑比较复杂时,还是需要声明函数

  • 6.2 当函数体只由单个表达式组成时,忽略掉括号。Otherwise,还是使用括号和return吧。
//bad
[1,2,3].map(number => {
  const nextNumber = number + 1;
  `A string containing the ${nextNumber}.`;
})
//good
[1,2,3].map(number => `A string containing the ${number+1}.`)
  • 6.3 如果函数只由单个表达式组成时,就可以不用小括号

这样可以减少视觉上的混淆

  //bad
  [1,2,3].map((x) => x * x);
  //good
  [1,2,3].map(x => x * x);

Modules

  • 7.1 相同路径引入的模块放在同一个地方
  // bad 
  import foo from 'foo'; 
  // … some other imports … 
  import { named1, named2 } from 'foo';
  //good
  import foo, { named1, named2 } from 'foo';
  • 7.2 不要 export 一个变量,只有常量才能被 export
  • 7.3 当文件中只有一个export, 就是用 default export
  • 7.4 将所有的 import 都放在的开始位置
  • 7.5
  \\ bad
  import {longNameA, longNameB, longNameC, longNameD, longNameE} from 'path';
  \\ good
  import {
    longNameA, 
    longNameB, 
    longNameC, 
    longNameD, 
    longNameE
  } from 'path';

注释

  • 8.1 使用 /** ... */进行多行注释
// good
/** 
    * make() returns a new element 
    * based on the passed-in tag name 
*/

分号

  • 9 总是使用分号

命名

  • 10.1 不要使用单个的单词来命名,命名需要有描述性
  • 10.2 使用驼峰式命名 objects, functions, and instances
  • 10.3 使用PascalCase 来命名构造函数和class, 以及组件名
  • 10.4 不要再变量开头或者结尾使用下划线
  • 10.5 使用驼峰式来命名 export-default 的模块
 function makeStyleGuide() {}
  export default makeStyleGuide;
  • 10.6 使用PascalCase 来命名 export 的 constructor / class / singleton / function library / bare object.

使用带类型判断的比较判断

使用 === 精确的比较操作符,避免在判断的过程中,由 JavaScript 的强制类型转换所造成的困扰。
如果你使用 === 操作符,那比较的双方必须是同一类型为前提的条件下才会有效。
在只使用 == 的情况下,JavaScript 所带来的强制类型转换使得判断结果跟踪变得复杂。

未完待续。。。。

你可能感兴趣的:(前端项目规范)