亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

Airbnb的JavaScript風格指南(ES5)

標簽:
JavaScript

用合理的方式编写JavaScript
原文链接

类型

  • 基本类型: 对于基本类型的操作是对值的操作。

    var foo = 1;var bar = foo;
    
    bar = 9;console.log(foo, bar); // => 1, 9
    • string

    • number

    • boolean

    • null

    • undefined

  • 复杂类型: 对于复杂类型的操作是对引用的操作。

    var foo = [1, 2];var bar = foo;
    
    bar[0] = 9;console.log(foo[0], bar[0]); // => 9, 9
    • object

    • array

    • function

对象

  • 尽量使用字面量创建对象。

    // 不推荐var item = new Object();// 推荐var item = {};
  • 不要使用保留字作为属性键值(在IE8中不被支持),查看

数组

字符串

  • 使用单引号''定义字符串.

    // 不推荐var name = "Bob Parr";// 推荐var name = 'Bob Parr';// 不推荐var fullName = "Bob " + this.lastName;// 推荐var fullName = 'Bob ' + this.lastName;
  • 超过100个字符的字符串应该写成多行形式并用字符串连接符+连接。

  • 注意: 如果过度使用字符串连接符可能会影响性能。jsPerf &

  • 当你需要在代码中构建字符串时,使用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;// 不推荐function inbox(messages) {
      items = '<ul>';  for (i = 0; i < length; i++) {
        items += '<li>' + messages[i].message + '</li>';
      }  return items + '</ul>';
    }// 推荐function inbox(messages) {
      items = [];  for (i = 0; i < length; i++) {
        items[i] = '<li>' + messages[i].message + '</li>';
      }  return '<ul>' + items.join('') + '</ul>';
    }

函数

属性

变量

变量提升

比较运算符

  • 使用===!==比使用==!=更理想.

  • 条件语句(例如if语句)在判断表达式值的时候,会使用ToBoolean抽象方法将结果强制转化为布尔型,转化规则如下:

    if ([0]) {  // true
      // 数组是一个对象, 对象会被转化为true}
    • Objects转化为true

    • Undefined转化为false

    • Null转化为false

    • Booleans不变

    • Numbers如果是+0, -0或NaN转化为false, 否则转化为true

    • Strings如果是空字符串''转化为false, 否则转化为true

  • 使用简短形式。

    // 不推荐if (name !== '') {  // ...stuff...}// 推荐if (name) {  // ...stuff...}// 不推荐if (collection.length > 0) {  // ...stuff...}// 推荐if (collection.length) {  // ...stuff...}
  • 更多信息参考Truth Equality and JavaScript by Angus Croll.

代码块

  • 多行的代码块使用大括号包围。

    // 不推荐if (test)  return false;// 推荐if (test) return false;// 推荐if (test) {  return false;
    }// 不推荐function () { return false; }// 推荐function () {  return false;
    }
  • 如果使用多行形式的ifelse代码块,将else放在if块关闭大括号的同一行。

    // 不推荐if (test) {
      thing1();
      thing2();
    }else {
      thing3();
    }// 推荐if (test) {
      thing1();
      thing2();
    } else {
      thing3();
    }

注释

  • 多行注释使用/** ... */,包括描述,参数类型和值,返回值等信息。

    // 不推荐// make() returns a new element// based on the passed in tag name//// @param {String} tag// @return {Element} elementfunction make(tag) {  // ...stuff...
    
      return element;
    }// 推荐/**
     * make() returns a new element
     * based on the passed in tag name
     *
     * @param {String} tag
     * @return {Element} element
     */function make(tag) {  // ...stuff...
    
      return element;
    }
  • 单行注释使用//,单行注释放在被注释内容的前一行,并在注释前留一个空行。

    // 不推荐var active = true;  // is current tab// 推荐// is current tabvar active = true;// 不推荐function getType() {  console.log('fetching type...');  // set the default type to 'no type'
      var type = this._type || 'no type';  return type;
    }// 推荐function getType() {  console.log('fetching type...');  // set the default type to 'no type'
      var type = this._type || 'no type';  return type;
    }
  • 如果你想指出一个需要重新审查的问题或是想提出一个未解决问题的实现思路,用FIXMETODO在注释中做出标注,这样可以帮助其他开发者快速理解你的意图,这样的注释和普通注释不一样,因为他们是需要被处理的。处理方式为:FIXME -- 需要解决问题或者TODO -- 需要被实现

  • 使用// FIXME:标注问题.

    function Calculator() {  // FIXME: 不应该使用全局变量
      total = 0;  return this;
    }
  • 使用// TODO:指出实现方式。

    function Calculator() {  // TODO: total应该被配置到一个options参数中
      this.total = 0;  return this;
    }

空白符

  • 使用soft tabs并设置成2个空格。

    // 不推荐function () {
    ∙∙∙∙var name;
    }// 不推荐function () {
    ∙var name;
    }// 推荐function () {
    ∙∙var name;
    }
  • 左大括号之前留一个空格。

    // 不推荐function test(){  console.log('test');
    }// 推荐function test() {  console.log('test');
    }// 不推荐dog.set('attr',{  age: '1 year',  breed: 'Bernese Mountain Dog'});// 推荐dog.set('attr', {  age: '1 year',  breed: 'Bernese Mountain Dog'});
  • 控制语句(如if, while)的左小括号前留一个空格,函数的参数列表前不要留空格。

    // 不推荐if(isJedi) {
      fight ();
    }// 推荐if (isJedi) {
      fight();
    }// 不推荐function fight () {  console.log ('Swooosh!');
    }// 推荐function fight() {  console.log('Swooosh!');
    }
  • 将运算符用空格隔开。

    // 不推荐var x=y+5;// 推荐var x = y + 5;
  • 文件最后以一个单独的换行符结尾。

    // 不推荐(function (global) {  // ...stuff...})(this);
    // 不推荐(function (global) {  // ...stuff...})(this);
    
    // 推荐(function (global) {  // ...stuff...})(this);
  • 遇到很长的方法调用链,使用换行缩进的方式(参照下面的代码),并以点号.开头,强调此行是一个方法而非一个新的语句。

    // 不推荐$('#items').find('.selected').highlight().end().find('.open').updateCount();// 不推荐$('#items').
      find('.selected').
        highlight().
        end().
      find('.open').
        updateCount();// 推荐$('#items')
      .find('.selected')
        .highlight()
        .end()
      .find('.open')
        .updateCount();// 不推荐var leds = stage.selectAll('.led').data(data).enter().append('svg:svg').classed('led', true)
        .attr('width', (radius + margin) * 2).append('svg:g')
        .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')')
        .call(tron.led);// 推荐var leds = stage.selectAll('.led')
        .data(data)
      .enter().append('svg:svg')
        .classed('led', true)
        .attr('width', (radius + margin) * 2)
      .append('svg:g')
        .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')')
        .call(tron.led);
  • 在代码块结束和新语句之间留一个空行。

    // 不推荐if (foo) {  return bar;
    }return baz;// 推荐if (foo) {  return bar;
    }return baz;// 不推荐var obj = {  foo: function () {
      },  bar: function () {
      }
    };return obj;// 推荐var obj = {  foo: function () {
      },  bar: function () {
      }
    };return obj;

逗号

  • 放在行首的逗号: 不要使用!

    // 不推荐var story = [
        once
      , upon
      , aTime
    ];// 推荐var story = [
      once,
      upon,
      aTime
    ];// 不推荐var hero = {    firstName: 'Bob'
      , lastName: 'Parr'
      , heroName: 'Mr. Incredible'
      , superPower: 'strength'};// 推荐var hero = {  firstName: 'Bob',  lastName: 'Parr',  heroName: 'Mr. Incredible',  superPower: 'strength'};
  • 对象或数组末尾额外的逗号: 不要使用! 这在IE6/7或IE9的quirks模式会导致一些问题。在一些ES3的实现中额外的逗号还会影响数组的长度计算,  这个问题在ES5 (source)中已经被明确了:

Edition 5 clarifies the fact that a trailing comma at the end of an ArrayInitialiser does not add to the length of the array. This is not a semantic change from Edition 3 but some implementations may have previously misinterpreted this.

```javascript// 不推荐var hero = {
  firstName: 'Kevin',
  lastName: 'Flynn',
};var heroes = [  'Batman',  'Superman',
];// 推荐var hero = {
  firstName: 'Kevin',
  lastName: 'Flynn'};var heroes = [  'Batman',  'Superman'];
```

分号

  • 请使用!

    // 不推荐(function () {  var name = 'Skywalker'
      return name
    })()// 推荐(function () {  var name = 'Skywalker';  return name;
    })();// 推荐 (当两个定义了立即执行函数的文件被连接使用的时候可以防止意外的错误);(function () {  var name = 'Skywalker';  return name;
    })();

    了解更多

类型转化和强制转化

  • 在语句开始的时候执行类型强制转换。

  • 字符串:

    //  => this.reviewScore = 9;// 不推荐var totalScore = this.reviewScore + '';// 推荐var totalScore = '' + this.reviewScore;// 不推荐var totalScore = '' + this.reviewScore + ' total score';// 推荐var totalScore = this.reviewScore + ' total score';
  • 数字类型转换时使用parseInt,并且总是带上基数。

    var inputValue = '4';// 不推荐var val = new Number(inputValue);// 不推荐var val = +inputValue;// 不推荐var val = inputValue >> 0;// 不推荐var val = parseInt(inputValue);// 推荐var val = Number(inputValue);// 推荐var val = parseInt(inputValue, 10);
  • 如果你遇到一些极端情况,parseInt成为了瓶颈,并且因为性能因素需要使用移位操作,留下注释来解释你这么做的原因。

    // 推荐/**
     * parseInt是我代码缓慢的元凶,
     * 使用移位操作来将字符串转换成数字可解此忧
     */var val = inputValue >> 0;
  • 注意: 使用移位操作的时候请注意,数字(Number)类型是一个64位值,但是移位操作总是会返回一个32位整数(source)。在处理大于32位整数的值的时候,移位操作会导致一些无法预测的现象。讨论。32位有符号整型数的最大值为2,147,483,647:

    2147483647 >> 0 //=> 21474836472147483648 >> 0 //=> -21474836482147483649 >> 0 //=> -2147483647
  • 布尔型:

    var age = 0;// 不推荐var hasAge = new Boolean(age);// 推荐var hasAge = Boolean(age);// 推荐var hasAge = !!age;

命名规范

  • 避免单字母的命名,尽量使用有意义的命名方式。

    // 不推荐function q() {  // ...stuff...}// 推荐function query() {  // ..stuff..}
  • 对象、函数、实例命名时,使用骆驼命名(小驼峰命名)。

    // 不推荐var OBJEcttsssss = {};var this_is_my_object = {};var o = {};function c() {}// 推荐var thisIsMyObject = {};function thisIsMyFunction() {}
  • 构造方法或类的命名使用帕斯卡命名(大驼峰命名)。

    // 不推荐function user(options) {  this.name = options.name;
    }var bad = new user({  name: 'nope'});// 推荐function User(options) {  this.name = options.name;
    }var good = new User({  name: 'yup'});
  • 命名私有属性的时候,以下划线_开头。

    // 不推荐this.__firstName__ = 'Panda';this.firstName_ = 'Panda';// 推荐this._firstName = 'Panda';
  • 要保存一个到this的引用,请使用_this来命名变量。

    // 不推荐function () {  var self = this;  return function () {    console.log(self);
      };
    }// 不推荐function () {  var that = this;  return function () {    console.log(that);
      };
    }// 推荐function () {  var _this = this;  return function () {    console.log(_this);
      };
    }
  • 给你的函数命名,这将有利于调试时代码栈的追踪。

    // 不推荐var log = function (msg) {  console.log(msg);
    };// 推荐var log = function log(msg) {  console.log(msg);
    };
  • 注意: 命名的函数表达式在IE8或以下版本会有一些怪异的表现。参考

属性存取器

构造器

事件

模块

jQuery

-jQuery对象的变量命名以$开头。

```javascript// 不推荐var sidebar = $('.sidebar');// 推荐var $sidebar = $('.sidebar');
```

ECMAScript 5兼容性

测试

  • 务必进行测试!

    function () {  return true;
    }

性能

资源

请阅读下面链接的内容

工具

其他的代码风格指南

其他的代码风格

深入阅读

参考书籍

博客

播客

License

(The MIT License)

Copyright (c) 2014 Airbnb

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.



作者:黄炜杰
链接:https://www.jianshu.com/p/87c10daab4f4


點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消