js 代码风格(2)

Properties
 
 • 当访问属性的时候,我们使用点(.)操作符。
复制代码
var luke = {
  jedi: true,
  age: 28
};

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

// good
var isJedi = luke.jedi;
复制代码

 • 当以变量的方式访问属性的时候,用下标符号([])。——除非特殊需求,否则尽量避免使用obj[variable]的方式进行属性访问。

复制代码
var luke = {
  jedi: true,
  age: 28
};

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

var isJedi = getProp('jedi');
复制代码
Variables
 
 • 总是使用var定义变量,否则会导致产生隐含全局变量。我们要尽量避免污染全局变量命名空间。
// bad
superPower = new SuperPower();

// good
var superPower = new SuperPower();

汤姆大叔—javascript系列文章中提到“JavaScript有隐含的全局概念,意味着你不声明的任何变量都会成为一个全局对象属性。在技术上,隐式全局变量并不是真正的全局变量,但它们是全局对象的属性。属性是可以通过delete操作符删除的,而变量是不能的。"

 • 使用一个var定义多个变量,每个变量在一个新行上。
复制代码
// bad
var items = getItems();
var goSportsTeam = true;
var dragonball = 'z';

// good
var items = getItems(),
    goSportsTeam = true,
    dragonball = 'z';
复制代码

 • 用var定义多个变量的时候,把不进行赋值的变量放置到最后——这是相当有益的。尤其是当你的变量需要前面变量值的时候。

复制代码
// bad
var i, len, dragonball,
    items = getItems(),
    goSportsTeam = true;

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

// good
var items = getItems(),
    goSportsTeam = true,
    dragonball,
    length,
    i;
复制代码

 • 把你的赋值变量放置在当前作用域的顶端。这将避免变量声明和hoisting(悬置/置顶解析/预解析)的问题。

复制代码
// 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;
  }

  return true;
}

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

  var name = getName();

  return true;
}
复制代码
Hoisting
 
汤姆大叔:
  1、JavaScript中,你可以在函数的任何位置声明多个var语句,并且它们就好像是在函数顶部声明一样发挥作用,这种行为称为 hoisting(悬置/置顶解析/预解析)。
  2、对于JavaScript,只 要你的变量是在同一个作用域中(同一函数),它都被当做是声明的,即使是它在var声明前使用的时候。
 •  变量声明提升到当前作用域的顶端,而它们的赋值操作不一定要这么做。
复制代码
function example() {
  console.log(notDefined); // => throws a ReferenceError
}


function example() {
  console.log(declaredButNotAssigned); // => undefined
  var declaredButNotAssigned = true;
}


function example() {
  var declaredButNotAssigned;
  console.log(declaredButNotAssigned); // => undefined
  declaredButNotAssigned = true;
}
复制代码

 •  匿名表达式会自动提升它们的变量名称(也就是说在var anonymous上面,example函数就已经知道有这个变量了),但是它们的函数体不会。

复制代码
function example() {
  console.log(anonymous); // => undefined

  anonymous(); // => TypeError anonymous is not a function

  var anonymous = function() {
    console.log('anonymous function expression');
  };
}
复制代码

 •  命名函数表达式也会提升它们的变量名称,而它们的函数名称和函数体不会这样做。

复制代码
function example() {
  console.log(named); // => undefined

  named(); // => TypeError named is not a function

  superPower(); // => ReferenceError superPower is not defined

  var named = function superPower() {
    console.log('Flying');
  };


  function example() {
    console.log(named); // => undefined

    named(); // => TypeError named is not a function

    var named = function named() {
      console.log('named');
    };
  }
}
复制代码

 •  注意:函数声明会提升它们的变量名称还有它们的函数体

复制代码
function example() {
  superPower(); // => Flying

  function superPower() {
    console.log('Flying');
  }
}
复制代码

  

Conditional Expressions & Equality
 
 •  使用 === 和 !== 代替==和!=。
== 和 != 会进行隐式类型转换,所以建议使用===和!==。
 •  强制使用对象的特性(ToBoolean)得到条件表达式的值,大致遵循以下简单规则。
  ◊ Objects 得到的值是true。
  ◊ Undefined得到的值是false。
  ◊ Null得到的值是false。
  ◊ Booleans得到的值是Boolean值(呵呵,当然)。
  ◊ Numbers 得到的值是:如果是+0,-0,或者NaN就是false,否则就是true。
  ◊ Strings 得到的值是:如果是'',就是false,否则就是true。
if ([0]) {
  // true
  // An array is an object, objects evaluate to true
}

 •  使用快捷方式。

复制代码
// bad
if (name !== '') {
  // ...stuff...
}

// good
if (name) {
  // ...stuff...
}

// bad
if (collection.length > 0) {
  // ...stuff...
}

// good
if (collection.length) {
  // ...stuff...
}


Blocks
 
• 有{}的代码,我们换行处理。
复制代码
// bad
if (test)
  return false;

// good
if (test) return false;

// good
if (test) {
  return false;
}

// bad
function() { return false; }

// good
function() {
  return false;
}
复制代码
Comments
 
• 对于多行注释使用/**  ... */。包含描述信息、参数类型和返回值。
 
复制代码
// bad
// make() returns a new element
// based on the passed in tag name
//
// @param <String> tag
// @return <Element> element
function make(tag) {

  // ...stuff...

  return element;
}

// good
/**
 * make() returns a new element
 * based on the passed in tag name
 *
 * @param <String> tag
 * @return <Element> element
 */
function make(tag) {

  // ...stuff...

  return element;
}
复制代码
• 对于单行注释使用//。单行注释单独放置在一个新行上。在注释前面放置一个空行。
复制代码
// bad
var active = true;  // is current tab

// good
// is current tab
var active = true;

// bad
function getType() {
  console.log('fetching type...');
  // set the default type to 'no type'
  var type = this._type || 'no type';

  return type;
}

// good
function getType() {
  console.log('fetching type...');

  // set the default type to 'no type'
  var type = this._type || 'no type';

  return type;
}
复制代码

• 对于一些问题,注释前加FIXME或TODO,这样将快速帮助开发者快速明白代码意图。

• 使用 // FIXME: 注释问题

复制代码
function Calculator() {

  // FIXME: shouldn't use a global here
  total = 0;

  return this;
}
复制代码

• 使用 // TODO: 注释问题的解决方案

复制代码
function Calculator() {

  // TODO: total should be configurable by an options param
  this.total = 0;

  return this;
}
复制代码
Type Casting & Coercion
 
• 在声明之前执行强制类型转换。
• 字符串
复制代码
//  => this.reviewScore = 9;

// bad
var totalScore = this.reviewScore + '';

// good
var totalScore = '' + this.reviewScore;

// bad
var totalScore = '' + this.reviewScore + ' total score';

// good
var totalScore = this.reviewScore + ' total score';
复制代码

 • 对于数字转换,使用parseInt,而且要带着类型转换的基数。

 • 如果parseInt成为你的瓶颈,处于性能原因,需要你使用“位移”操作。那么请写下注释解释你这样做的原因。

复制代码
var inputValue = '4';

// bad
var val = new Number(inputValue);

// bad
var val = +inputValue;

// bad
var val = inputValue >> 0;

// bad
var val = parseInt(inputValue);

// good
var val = Number(inputValue);

// good
var val = parseInt(inputValue, 10);

// good
/**
 * parseInt 使我的代码变慢.
 * 为了提高速度,使用位移操作让字符串强制转化为数字。
 */
var val = inputValue >> 0;
复制代码

 • 布尔

复制代码
var age = 0;

// bad
var hasAge = new Boolean(age);

// good
var hasAge = Boolean(age);

// good
var hasAge = !!age;
复制代码
Constructors
 
 • 用方法扩展对象,而不是用一个新对象。
复制代码
function Jedi() {
  console.log('new jedi');
}

// bad
Jedi.prototype = {
  fight: function fight() {
    console.log('fighting');
  },

  block: function block() {
    console.log('blocking');
  }
};

// good
Jedi.prototype.fight = function fight() {
  console.log('fighting');
};

Jedi.prototype.block = function block() {
  console.log('blocking');
};
复制代码
  • 让对象的方法return this,这样有利于方法的链锁操作。
 
复制代码
// bad
Jedi.prototype.jump = function() {
  this.jumping = true;
  return true;
};

Jedi.prototype.setHeight = function(height) {
  this.height = height;
};

var luke = new Jedi();
luke.jump(); // => true
luke.setHeight(20) // => undefined

// good
Jedi.prototype.jump = function() {
  this.jumping = true;
  return this;
};

Jedi.prototype.setHeight = function(height) {
  this.height = height;
  return this;
};

var luke = new Jedi();

luke.jump()
  .setHeight(20);
复制代码

  • 我们可以自定义一个toString()方法。——要确保它能正常运行,而且不会产生其他影响。

复制代码
function Jedi(options) {
  options || (options = {});
  this.name = options.name || 'no name';
}

Jedi.prototype.getName = function getName() {
  return this.name;
};

Jedi.prototype.toString = function toString() {
  return 'Jedi - ' + this.getName();
};
复制代码
复制代码
原文地址:https://www.cnblogs.com/yelongsan/p/6297534.html