交了这么多年JavaScript学费,你掌握了多少(第二期)

不应尝试更新“ const”变量

声明为的变量const无法修改。不幸的是,这样做的尝试并不总是会引发错误。在非ES2015环境中,此类尝试可能会被忽略。

不兼容的代码示例:

const pi = "yes, please";
pi = 3.14;  // Noncompliant

布尔检查不应该反转

反转布尔比较的结果不必要地复杂。相反,应该进行相反的比较。

不兼容的代码示例:

if (!(a === 2)) { ... }  // Noncompliant

兼容解决方案:

if (a !== 2) { ... }

大括号和括号应与箭头功能一致使用

共享的编码约定使团队可以有效地协作。当带箭头功能的括号使用不符合所配置的要求时,此规则会引起问题。

不兼容的代码示例:

var foo = (a) => { /* ... */ };  // Noncompliant; remove parens from arg
var bar = (a, b) => { return 0; };  // Noncompliant; remove curly braces from body

兼容解决方案:

var foo = a => { /* ... */ };
var bar = (a, b) => 0;

数组方法的回调应具有return语句

JavaScript中的数组有几种用于过滤,映射或折叠的方法,这些方法需要回调。在这样的回调函数中没有return语句很可能是一个错误。

此规则适用于数组的以下方法:

  • Array.from
  • Array.prototype.every
  • Array.prototype.filter
  • Array.prototype.find
  • Array.prototype.findIndex
  • Array.prototype.map
  • Array.prototype.reduce
  • Array.prototype.reduceRight
  • Array.prototype.some
  • Array.prototype.sort

不兼容的代码示例:

var merged = arr.reduce(function(a,b){
  a.concat(b);
}; //不符合规定:没有返回声明

兼容解决方案:

var merged = arr.reduce(function(a, b) {
  return a.concat(b);
});

函数声明不应在块内进行

尽管大多数脚本引擎都支持块内的功能声明,但从浏览器到浏览器,实现之间是不一致的。

不兼容的代码示例:

if (x) {
  function foo() {} //foo is hoisted in Chrome, Firefox and Safari, but not in Edge.
}

兼容解决方案:

if (x) {
  var foo = function() {}
}

元素类型选择器不应与类选择器一起使用

在类选择器中使用元素类型比仅使用类选择器要慢。

不兼容的代码示例:

var $products = $("div.products");    // Noncompliant - slow

兼容解决方案:

var $products = $(".products");    // Compliant - fast

函数参数,捕获的异常和foreach变量的初始值不应忽略

从功能体内分配参数在技术上是正确的,但它降低了代码的可读性,因为开发人员无法在不经历整个功能的情况下就无法确定是否正在访问原始参数或某些临时变量。而且,某些开发人员可能还希望函数参数的分配对调用者可见,但事实并非如此,这种缺乏可见性可能会使他们感到困惑。相反,所有参数,捕获的异常和foreach参数都应视为常量。

不兼容的代码示例:

function MyClass(name, strings) {
  name = foo;                    // Noncompliant

  for (var str of strings) {
    str = "";  // Noncompliant
  }
}

带有和不带有“ new”的函数都不应被调用

创建新对象实例的构造函数只能用调用new。非构造函数一定不能。将这两种用法混合使用可能会在运行时导致意外结果。

不兼容的代码示例:

function getNum() {
  return 5;
}

function Num(numeric, alphabetic) {
  this.numeric = numeric;
  this.alphabetic = alphabetic;
}

var myFirstNum = getNum();
var my2ndNum = new getNum();  // Noncompliant. An empty object is returned, NOT 5

var myNumObj1 = new Num();
var myNumObj2 = Num();  // Noncompliant. undefined is returned, NOT an object

不应使用HTML样式的注释

HTML样式的注释不是EcmaScript规范的一部分,因此不应使用。

不兼容的代码示例:

<!-- Noncompliant -->

兼容解决方案:

// Compliant
/* Compliant */

二进制运算符的两侧不应使用相同的表达式

在二元运算符的任一侧使用相同的值几乎总是一个错误。在逻辑运算符的情况下,它要么是复制/粘贴错误, 要么是浪费的代码,应简化。在按位运算符和大多数二进制数学运算符的情况下,在运算符的两边具有相同的值会产生可预测的结果,因此应简化。

不兼容的代码示例:

if (a == b && a == b) { // if the first one is true, the second one is too
  doX();
}
if (a > a) { // always false
  doW();
}

var j = 5 / 5; //always 1
var k = 5 - 5; //always 0

例外情况:针对其自身测试一个变量的特定情况对于而言是有效的测试,NaN因此将被忽略。

类似地,左移1到1在位掩码的构造中很常见,并且被忽略。

此外,逗号运算符,和instanceof运算符会被忽略,因为当使用有效时,存在用例。

if (f !== f) { // test for NaN value
  console.log("f is NaN");
}

var i = 1 << 1; // Compliant
var j = a << a; // Noncompliant

增量(++)和减量(-)运算符不应在方法调用中使用,或与表达式中的其他运算符混合使用

不建议在方法调用中或与其他算术运算符结合使用递增和递减运算符,因为:

  • 这会严重损害代码的可读性。
  • 它在语句中引入了其他副作用,并可能导致不确定的行为。
  • 与其他任何算术运算符隔离使用这些运算符会更安全。

不兼容的代码示例:

u8a = ++u8b + u8c--;
foo = bar++ / 4;

兼容解决方案:

++u8b;
u8a = u8b + u8c;
u8c--;
foo = bar / 4;
bar++;

局部变量不应先声明然后立即返回或抛出

仅声明变量以立即返回或抛出该变量是一种不好的做法。

一些开发人员认为,这种做法提高了代码的可读性,因为它使他们能够明确命名返回的内容。但是,此变量是内部实现细节,不会向方法的调用者公开。方法名称应足以使调用者准确知道将返回什么。

不兼容的代码示例:

function computeDurationInMilliseconds() {
  var duration = (((hours * 60) + minutes) * 60 + seconds ) * 1000 ;
  return duration;
}

兼容解决方案:

function computeDurationInMilliseconds() {
  return (((hours * 60) + minutes) * 60 + seconds ) * 1000 ;
}

具有“null”或“undefined”值的变量的属性不应访问

为变量分配undefinednull值时,它没有属性。无论如何,尝试访问此类变量的属性都会TypeError导致,如果错误未在catch 块中捕获,则会导致脚本突然终止。但是catch最好不要完全避免这种情况。

不兼容的代码示例:

if (x === undefined) {
  console.log(x.length); // Noncompliant; TypeError will be thrown
}

“ in”和“ instanceof”的结果应取反,而不是操作数

混合操作顺序几乎总是会产生意想不到的结果。

同样,错误应用否定也会产生不良结果。例如考虑之间的差异!key in dict!(key in dict)。第一个在中寻找布尔值(!key)dict,另一个在寻找字符串并将结果取反。!obj instanceof SomeClass有同样的问题。

否定in or instanceof运算符的左操作数时,此规则会引起问题。

不兼容的代码示例:

if (!"prop" in myObj) {  // Noncompliant;  "in" operator is checking property "false"
  doTheThing();  // this block will be never executed
}

if (!foo instanceof MyClass) {  // Noncompliant; "!foo" returns a boolean, which is not an instance of anything
  doTheOtherThing();  // this block is never executed
}

兼容解决方案:

if (!("prop" in myObj)) {
  doTheThing();
}

if (!(foo instanceof MyClass)) {
  doTheOtherThing();
}

三元运算符不应嵌套

嵌套三元运算符会导致在你编写代码时看起来似乎很清晰的那种代码,但是六个月后,将使维护人员(或更糟糕的是,你将来可能会)陷入困境并大骂。

不兼容的代码示例:

function getTitle(p) {
  return p.gender == "male" ? "Mr. " : p.isMarried() ? "Mrs. " : "Miss ";  // Noncompliant
}

兼容解决方案:

function getTitle(p) {
  if (p.gender == "male") {
    return "Mr. ";
  }
  return p.isMarried() ? "Mrs. " : "Miss ";
}

不应使用全局“ this”对象

this对象之外使用关键字时,它指的是全局this对象,它与window标准网页中的对象相同 。这样的使用可能会使维护者感到困惑。相反,只需删除this,或将其替换为window;它将具有相同的效果,并且更具可读性。

不兼容的代码示例:

this.foo = 1;   // Noncompliant
console.log(this.foo); // Noncompliant

function MyObj() {
  this.foo = 1; // Compliant
}

MyObj.func1 = function() {
  if (this.foo == 1) { // Compliant
    // ...
  }
}

兼容解决方案:

foo = 1;
console.log(foo);

function MyObj() {
  this.foo = 1;
}

MyObj.func1 = function() {
  if (this.foo == 1) {
    // ...
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章