JavaScript 风格指南(4)

-- 接 JavaScript 风格指南(3) --


八、Arrow Functions


· 8.1 当你必须使用函数表达式(如传递匿名函数时),请使用箭头函数表示法。


理由:this 的执行上下文不会改变,写法也更简洁。
// bad
[1, 2, 3].map(function (x) {
  const y = x + 1;
  return x * y;
});

// good
[1, 2, 3].map((x) => {
  const y = x + 1;
  return x * y;
});


· 8.2 如果函数体由一个语句组成,返回一个没有副作用的表达式,省略括号并使用隐式返回。否则,保留括号并使用返回语句。


理由:这属于 ES6 的语法糖,可读性更好。

// 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}.`);

// good
[1, 2, 3].map((number) => {
  const nextNumber = number + 1;
  return `A string containing the ${nextNumber}.`;
});

// good
[1, 2, 3].map((number, index) => ({
  [index]: number,
}));

// 无副作用的隐式返回
function foo(callback) {
  const val = callback();
  if (val === true) {
    // Do something if callback returns true
  }
}

let bool = false;

// bad
foo(() => bool = true);

// good
foo(() => {
  bool = true;
});


· 8.3 如果表达式跨越多行,则用括号括起来以提高可读性。


理由:它能够清楚地显示出函数的开始和结束位置。

// bad
['get', 'post', 'put'].map(httpMethod => Object.prototype.hasOwnProperty.call(
    httpMagicObjectWithAVeryLongName,
    httpMethod,
  )
);

// good
['get', 'post', 'put'].map(httpMethod => (
  Object.prototype.hasOwnProperty.call(
    httpMagicObjectWithAVeryLongName,
    httpMethod,
  )
));


· 8.4 如果函数只有1个参数,并且函数体没有使用大括号,则可以省略参数的圆括号。否则,始终将圆括号括在参数外以确保清晰和一致性。


理由:减少视觉混乱。

// bad
[1, 2, 3].map((x) => x * x);

// good
[1, 2, 3].map(x => x * x);

// good
[1, 2, 3].map(number => (
  `A long string with the ${number}. It’s so long that we don’t want it to take up space on the .map line!`
));

// bad
[1, 2, 3].map(x => {
  const y = x + 1;
  return x * y;
});

// good
[1, 2, 3].map((x) => {
  const y = x + 1;
  return x * y;
});


· 8.5 避免将箭头函数语法(=>)与比较运算符混淆(< =,> =)

// bad
const itemHeight = item => item.height > 256 ? item.largeSize : item.smallSize;

// bad
const itemHeight = (item) => item.height > 256 ? item.largeSize : item.smallSize;

// good
const itemHeight = item => (item.height > 256 ? item.largeSize : item.smallSize);

// good
const itemHeight = (item) => {
  const { height, largeSize, smallSize } = item;
  return height > 256 ? largeSize : smallSize;
};


九、Classes & Constructors


· 9.1 总是使用类,避免直接操作原型。


理由:class 语法更简洁,读起来更友好。

// bad
function Queue(contents = []) {
  this.queue = [...contents];
}
Queue.prototype.pop = function () {
  const value = this.queue[0];
  this.queue.splice(0, 1);
  return value;
};

// good
class Queue {
  constructor(contents = []) {
    this.queue = [...contents];
  }
  pop() {
    const value = this.queue[0];
    this.queue.splice(0, 1);
    return value;
  }
}


· 9.2 使用 extends 实现继承


理由:它是属于一种内嵌的方式,用来继承原型的功能,同时又不破坏实例。

// bad
const inherits = require('inherits');
function PeekableQueue(contents) {
  Queue.apply(this, contents);
}
inherits(PeekableQueue, Queue);
PeekableQueue.prototype.peek = function () {
  return this.queue[0];
};

// good
class PeekableQueue extends Queue {
  peek() {
    return this.queue[0];
  }
}


· 9.3 方法最后都返回 this,这样有助于链式调用。

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

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

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

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

  setHeight(height) {
    this.height = height;
    return this;
  }
}

const luke = new Jedi();

luke.jump()
  .setHeight(20);

· 9.4 在类内部重写个 toString() 方法也无所谓,保证它能正常工作并且没有副作用就行。

class Jedi {
  constructor(options = {}) {
    this.name = options.name || 'no name';
  }

  getName() {
    return this.name;
  }

  toString() {
    return `Jedi - ${this.getName()}`;
  }
}


· 9.5 如果没有指定构造函数,则类具有默认的构造函数。空构造函数或只委托父类的函数是不必要的。

// bad
class Jedi {
  constructor() {}

  getName() {
    return this.name;
  }
}

// bad
class Rey extends Jedi {
  constructor(...args) {
    super(...args);
  }
}

// good
class Rey extends Jedi {
  constructor(...args) {
    super(...args);
    this.name = 'Rey';
  }
}

· 9.6 避免重复声明类成员。


理由:后面的会覆盖前面的。

// bad
class Foo {
  bar() { return 1; }
  bar() { return 2; }
}

// good
class Foo {
  bar() { return 1; }
}

// good
class Foo {
  bar() { return 2; }
}


参考文章: JavaScript 风格指南

-- 未完待续 --


猜你喜欢

转载自blog.csdn.net/ghostlpx/article/details/76585784