AirbnbJavaScript风格指南

作者:高天阳

邮箱:[email protected]

更改历史

* 2018-09-14    高天阳    更新目录
* 2017-11-14    高天阳    初始化文档

1 目录

  1. 类型
  2. 对象
  3. 数组
  4. 字符串
  5. 函数
  6. 属性
  7. 变量
  8. 提升
  9. 比较运算符和等号
  10. 注释
  11. 空白
  12. 逗号
  13. 分号
  14. 类型转化
  15. 命名规则
  16. 存取器
  17. 构造函数
  18. 事件
  19. 模块
  20. jQuery的
  21. ECMAScript 5兼容性
  22. 测试
  23. 性能
  24. 资源
  25. 谁在使用
  26. 翻译
  27. JavaScript风格指南说明
  28. 与我们讨论JavaScript
  29. 贡献者
  30. 许可

2 正文

2.1 类型

  • 原始值:存取直接作用于它自身。
    • string
    • number
    • boolean
    • null
    • undefined
var foo = 1;
var bar = foo;

bar = 9;

console.log(foo, bar); // => 1, 9
  • 复杂类型:存在时作用于它自身值的引用。
    • object
    • array
    • function
var foo = [1, 2];
var bar = foo;

bar[0] = 9;

console.log(foo[0], bar[0]); // => 9, 9

2.2 对象

  • 使用直接量创建对象。
// bad
var item = new Object();

// good
var item = {};
// bad
var superman = {
  default: { clark: 'kent' },
  private: true
};

// good
var superman = {
  defaults: { clark: 'kent' },
  hidden: true
};
  • 使用同义词替换需要使用的保留字。
// bad
var superman = {
  class: 'alien'
};

// bad
var superman = {
  klass: 'alien'
};

// good
var superman = {
  type: 'alien'
};

2.3 数组

  • 使用直接量创建数组。
// bad
var items = new Array();

// good
var items = [];
  • 向数组增加元素时使用Array#push来替代直接赋值。

javascript

var someStack = [];

// bad
someStack[someStack.length] = 'abracadabra';

// good
someStack.push('abracadabra');
var len = items.length;
var itemsCopy = [];
var i;

// bad
for (i = 0; i < len; i++) {
  itemsCopy[i] = items[i];
}

// good
itemsCopy = items.slice();

Demo

// bad
var a = [1,2,3];
var b = a;

console.log(a);// => [1,2,3]
console.log(b);// => [1,2,3]

a[0]=4;

console.log(a);// => [4,2,3]
console.log(b);// => [4,2,3]
// bad
var a = [1,2,3];
var b = [];

console.log(a);// => [1,2,3]
console.log(b);// => []

for(var i=0; i<a.length; i++){b[i]=a[i]}

console.log(a);// => [1,2,3]
console.log(b);// => [1,2,3]

a[0]=4;

console.log(a);// => [4,2,3]
console.log(b);// => [1,2,3]
// good
var a = [1,2,3];
var b = a.slice();

console.log(a);// => [1,2,3]
console.log(b);// => [1,2,3]

a[0]=4;

console.log(a);// => [4,2,3]
console.log(b);// => [1,2,3]
function trigger() {
  var args = Array.prototype.slice.call(arguments);
  ...
}

Demo

function trigger() {
  var args = Array.prototype.slice.call(arguments);
  return args
}
function trigger2() {
  return arguments
}

// bad
a = trigger2('a','b','c','d') // 此时a为类数组对象
a.push('e');// => Uncaught TypeError: a.push is not a function

// good
a = trigger('a','b','c','d') // 此时a为数组对象
a.push('e');
console.log(a);// => ["a", "b", "c", "d", "e"]

2.4 字符串

  • 使用单引号''包裹字符串。
// bad
var name = "Bob Parr";

// good
var name = 'Bob Parr';

// bad
var fullName = "Bob " + this.lastName;

// good
var fullName = 'Bob ' + this.lastName;
  • 超过100个字符的字符串应该使用连接符写成多行。

  • 注:若过度使用,通过连接符连接的长字符串可能会影响性能。jsPerf讨论

// bad
var 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
var 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
var 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.';
  • 程序化生成的字符串使用Array#join连接而不是使用连接符。尤其是IE下:jsPerf
var items;
var messages;
var length;
var i;

messages = [{
  state: 'success',
  message: 'This one worked.'
}, {
  state: 'success',
  message: 'This one worked as well.'
}, {
  state: 'error',
  message: 'This one did not work.'
}];

length = messages.length;

// bad
function inbox(messages) {
  items = '<ul>';

  for (i = 0; i < length; i++) {
    items += '<li>' + messages[i].message + '</li>';
  }

  return items + '</ul>';
}

// good
function inbox(messages) {
  items = [];

  for (i = 0; i < length; i++) {
    // use direct assignment in this case because we're micro-optimizing.
    items[i] = '<li>' + messages[i].message + '</li>';
  }

  return '<ul>' + items.join('') + '</ul>';
}

2.5 函数

  • 函数表达式:
// 匿名函数表达式
var anonymous = function() {
  return true;
};

// 命名函数表达式
var named = function named() {
  return true;
};

// 立即调用的函数表达式(IIFE)
(function () {
  console.log('Welcome to the Internet. Please follow me.');
}());
  • 永远不要在一个非函数代码块(if,while等)中声明一个函数,把那个函数赋予给一个变量。但是它们的解析表现不一致。

  • 注意: ECMA-262定义为一组语句。函数声明不是语句。阅读对ECMA-262这个问题的说明

// bad
if (currentUser) {
  function test() {
    console.log('Nope.');
  }
}

// good
var test;
if (currentUser) {
  test = function test() {
    console.log('Yup.');
  };
}
  • 永远不要把参数命名为arguments。将这取代函数作用英文域内的arguments对象。
// bad
function nope(name, options, arguments) {
  // ...stuff...
}

// good
function yup(name, options, args) {
  // ...stuff...
}

2.6 属性

  • 使用.来访问对象的属性。
var luke = {
  jedi: true,
  age: 28
};

// bad
var isJedi = luke['jedi'];

// good
var isJedi = luke.jedi;
  • 当通过变量访问属性时使用中括号[]
var luke = {
  jedi: true,
  age: 28
};

function getProp(prop) {
  return luke[prop];
}

var isJedi = getProp('jedi');

2.7 变量

  • 使用总是var来声明变量。不这么做将导致产生全局变量。我们要避免污染全局命名空间。
// bad
superPower = new SuperPower();

// good
var superPower = new SuperPower();
  • 使用var声明每一个变量。

这样做的好处是增加新变量将变的更加容易,你而且永远不用再担心调换错;,

// bad
var items = getItems(),
    goSportsTeam = true,
    dragonball = 'z';

// bad
// (跟上面的代码比较一下,看看哪里错了)
var items = getItems(),
    goSportsTeam = true;
    dragonball = 'z';

// good
var items = getItems();
var goSportsTeam = true;
var dragonball = 'z';
  • 最后再声明未赋值的变量。当你需要引用前面的变量赋值时这将变的很有用。
// bad
var i, len, dragonball,
    items = getItems(),
    goSportsTeam = true;

// bad
var i;
var items = getItems();
var dragonball;
var goSportsTeam = true;
var len;

// good
var items = getItems();
var goSportsTeam = true;
var dragonball;
var length;
var i;
  • 在作用域顶部声明变量。这将帮你避免变量声明提升相关的问题。
// bad
function () {
  test();
  console.log('doing stuff..');

  //..other stuff..

  var name = getName();

  if (name === 'test') {
    return false;
  }

  return name;
}

// good
function () {
  var name = getName();

  test();
  console.log('doing stuff..');

  //..other stuff..

  if (name === 'test') {
    return false;
  }

  return name;
}

// bad - 不必要的函数调用
function () {
  var name = getName();

  if (!arguments.length) {
    return false;
  }

  this.setFirstName(name);

  return true;
}

// good
function () {
  var name;

  if (!arguments.length) {
    return false;
  }

  name = getName();
  this.setFirstName(name);

  return true;
}
  • ```angular2html

- 

```angular2html

难点:最佳实践,超出于示例,应该归纳总结出积累的技巧。

3 同类技术对比

难点:归纳比对项

参考资料

results matching ""

    No results matching ""