如何避免分号改进JavaScript代码?

时间:2017-08-04 13:20:06

标签: javascript

我正在阅读热门应用的JavaScript代码(非缩小版),我注意到它在某些地方完全没有分号,例如:

function bytesCmp (bytes1, bytes2) {
  var len = bytes1.length
  if (len != bytes2.length) {
    return false
  }

  for (var i = 0; i < len; i++) {
    if (bytes1[i] != bytes2[i]) {
      return false
    }
  }
  return true
}

function bytesXor (bytes1, bytes2) {
  var len = bytes1.length
  var bytes = []

  for (var i = 0; i < len; ++i) {
    bytes[i] = bytes1[i] ^ bytes2[i]
  }

  return bytes
}

function bytesToWords (bytes) {
  if (bytes instanceof ArrayBuffer) {
    bytes = new Uint8Array(bytes)
  }
  var len = bytes.length
  var words = []
  var i
  for (i = 0; i < len; i++) {
    words[i >>> 2] |= bytes[i] << (24 - (i % 4) * 8)
  }

  return new CryptoJS.lib.WordArray.init(words, len)
}

在JavaScript中不使用分号有什么好处?这只是文件大小吗?

1 个答案:

答案 0 :(得分:0)

绝对没有优势,应该避免这种做法作为最佳做法,因为在某些边缘情况下,省略分号会导致代码中出现错误。

这是一个常见的例子。在下面的代码中,我们有一个函数表达式,应该以分号结束。因为后跟一个以(开头的表达式,JavaScript运行时不会插入分号,而是错误地调用该函数,将括号中的表达式结果作为参数传递给函数。换句话说,JavaScript运行时没有看到函数表达式,后面跟着一个单独的三元表达式。它将该函数视为Immediately Invoked Function Expression(IIFE)。

var foo = function(){
  console.log("foo says hello!");
}  // <-- There should be a semicolon here, but it won't get inserted properly
(navigator.geolocation) ? console.log("Geolocation is supported.") : console.log("Geolocation is not supported");

上面的代码不仅错误地调用foo函数并将navigator.geolocation作为参数传递给它,而且还使用了该函数的返回值(此处为undefined)作为下一行三元表达式中的if条件,导致代码错误地确定Geolocation支持(实际上是它)。

但是,如果我们只是手动插入单个分号,就没有歧义,代码会正确执行(foo只会被分配给一个函数表达式,但是不会被调用,Geolocation会被单独的三元表达式正确地确定):

var foo = function(){
  console.log("foo says hello!");
};
(navigator.geolocation) ? console.log("Geolocation is supported.") : console.log("Geolocation is not supported");

在您提供的代码中,您有几个return语句。以下是不将分号放在那里的危险的一个例子:

function foo(){
  if(navigator.geolocation){
    return // <--- Often, people break up single statements on to separate lines
      true;
  }
}

console.log(foo());

在上面的示例中,return true被分解为不同的行(通常,这不是一个问题),但由于return是一个有效的完整语句,因此分号后面会错误地插入分号函数返回时没有正确的返回值。

正确的方法是:

function foo(){
  if(navigator.geolocation){
    return true;
  }
}

console.log(foo());

因此,正如您所看到的,选择不手动插入分号不仅仅是一种风格选择。它对代码的执行方式有实际意义。

由于这些情况您必须自己插入分号,您现在可以选择。

  1. 除了几个特殊情况外,不要将分号放入 必要时,这会导致编码方法不一致 并使其他人更难理解您的代码。
  2. 把它们放在一起,永远不会有这些类型的错误 代码。
  3. 与任何编码实践一样,如果由于实践可能会在您的代码中引入潜在的错误,当另一个易于实施的实践可以完全缓解这种危险时,应该避免潜在的有害做法。这就是为什么我们有“最佳实践”。 JavaScript有许多语法属于“只是因为你可以,并不意味着你应该”类别。