类型

基本类型:访问基本类型时,应该直接操作类型值

  1. string
  2. number
  3. boolean
  4. null
  5. undefined
var foo = 1;
var bar = foo;
bar = 9;
console.log(foo, bar); // => 1, 9

复合类型:访问复合类型时,应该操作其引用

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

对象

使用字面量语法创建对象

// bad
var item = new Object();
// good
var item = {};

不要使用保留字,在IE8中不起作用,更多相关信息

// 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'
};

数组

// bad
var items = new Array();
// good
var items = [];

添加数组元素时,使用push而不是直接添加

var someStack = [];
// bad
someStack[someStack.length] = 'abracadabra';
// good
someStack.push('abracadabra');

需要复制数组时,可以使用slice,jsPerf的相关文章

var len = items.length;
var itemsCopy = [];
var i;
// bad
for (i = 0; i < len; i++) {
itemsCopy[i] = items[i];
}
// good
itemsCopy = items.slice();

使用slice将类数组对象转为数组

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

字符串

对字符串使用单引号

// bad
var name = "Bob Parr";
// good
var name = 'Bob Parr';
// bad
var fullName = "Bob " + this.lastName;
// good
var fullName = 'Bob ' + this.lastName;

超过80个字符的字符串应该使用字符串连接符进行跨行

注意:对长字符串过度使用连接符将会影响性能。相关的文章和主题讨论: jsPerf & Discussion

// 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++) {
items[i] = '<li>' + messages[i].message + '</li>';
}
return '<ul>' + items.join('') + '</ul>';
}

函数

函数表达式

// anonymous function expression
var anonymous = function() {
return true;
};
// named function expression
var named = function named() {
return true;
};
// immediately-invoked function expression (IIFE)
(function() {
console.log('Welcome to the Internet. Please follow me.');
})();

不要在非函数块中(if, while, etc)声明函数,尽管浏览器允许你分配函数给一个变量,但坏消息是,不同的浏览器用不同的方式解析它

注意:ECMA-262把块定义为一组语句,但函数声明不是一个语句:Read ECMA-262’s note on this issue.

// 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...
}