前端项目规范

因为项目用的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 都放在<script></script>的开始位置
  • 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 所带来的强制类型转换使得判断结果跟踪变得复杂。

未完待续。。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容