本规范用于指导前端开发代码规范参考
#  1 常量#  1.1 使用 const 您的所有引用的 避免使用 var。为什么?这样可以确保您不能重新分配引用,这可能导致错误和难以理解的代码。
var  a =  1 var  b =  2 const  a =  1 const  b =  2 
#  1.2 如果必须重新分配引用,请使用 let 代替 var。为什么?let 是像块一样,而不是像函数一样 var。
var  count =  1 if  ( true )  {   count +=  1  } let  count =  1 if  ( true )  {   count +=  1  } 
#  1.3 请注意,let 和 const 都是块范围的。{   let  a =  1    const  b =  1  } console. log ( a)   console. log ( b)   
#  2 对象 Objects#  2.1 使用文字语法进行对象创建。const  item =  new  Object ( ) const  item =  { } 
#  2.2 创建具有动态属性名称的对象时,请使用计算的属性名称。为什么?它们使您可以在一处定义对象的所有属性。
function  getKey ( k )  {   return  ` a key named  ${ k} `  } const  obj =  {   id:  5 ,    name:  'San Francisco' ,  } obj[ getKey ( 'enabled' ) ]  =  true  const  obj =  {   id:  5 ,    name:  'San Francisco' ,    [ getKey ( 'enabled' ) ] :  true ,  } 
#  2.3 使用对象方法的简写。const  atom =  {   value:  1 ,    addValue :  function  ( value )  {      return  atom. value +  value   } ,  } const  atom =  {   value:  1 ,    addValue ( value )  {      return  atom. value +  value   } ,  } 
#  2.4 使用属性值速记为什么?它简短而具有描述性。
const  lukeSkywalker =  'Luke Skywalker' const  obj =  {   lukeSkywalker:  lukeSkywalker,  } const  obj =  {   lukeSkywalker,  } 
#  2.5 在对象声明的开头对速记属性进行分组为什么?比较容易分辨出哪些属性正在使用速记。
const  anakinSkywalker =  'Anakin Skywalker' const  lukeSkywalker =  'Luke Skywalker' const  obj =  {   episodeOne:  1 ,    twoJediWalkIntoACantina:  2 ,    lukeSkywalker,    episodeThree:  3 ,    mayTheFourth:  4 ,    anakinSkywalker,  } const  obj =  {   lukeSkywalker,    anakinSkywalker,    episodeOne:  1 ,    twoJediWalkIntoACantina:  2 ,    episodeThree:  3 ,    mayTheFourth:  4 ,  } 
2.6 仅引用无效标识符的属性
为什么?总的来说,我们认为它在主观上更容易阅读。它改善了语法突出显示的功能,并且也容易被许多 JS 引擎优化。
const  bad =  {   'foo' :  3 ,    'bar' :  4 ,    'data-blah' :  5 ,  } const  good =  {   foo:  3 ,    bar:  4 ,    'data-blah' :  5 ,  } 
#  2.7 不叫 Object.prototype 直接的方法,如 hasOwnProperty,propertyIsEnumerable 和 isPrototypeOf。为什么?这些方法可能会受到所讨论对象的属性的影响 - 考虑 {hasOwnProperty: false}- 或者该对象可能是空对象(Object.create (null))。
console. log ( object. hasOwnProperty ( key) )  console. log ( Object . prototype. hasOwnProperty . call ( object,  key) )  const  has =  Object . prototype. hasOwnProperty console. log ( has . call ( object,  key) )  import  has from  'has'  console. log ( has ( object,  key) )  
#  2.8 首选对象散布运算符,而不是 Object.assign 浅表复制对象。使用对象剩余运算符可获取省略了某些属性的新对象。const  original =  {  a:  1 ,  b:  2  } const  copy =  Object. assign ( original,  {  c:  3  } )  delete  copy. a const  original =  {  a:  1 ,  b:  2  } const  copy =  Object. assign ( { } ,  original,  {  c:  3  } )  const  original =  {  a:  1 ,  b:  2  } const  copy =  {  ... original,  c:  3  }  const  {  a,  ... noA }  =  copy 
#  3 数组 Array#  3.1 使用文字语法创建数组。const  items =  new  Array ( ) const  items =  [ ] 
#  3.2 使用 Array#push 而不是直接分配将项目添加到数组。const  someStack =  [ ] someStack[ someStack. length]  =  'abracadabra'  someStack. push ( 'abracadabra' )  
#  3.3 使用数组跨度... 复制数组。const  len =  items. lengthconst  itemsCopy =  [ ] let  ifor  ( i =  0  i <  len i +=  1 )  {   itemsCopy[ i]  =  items[ i]  } const  itemsCopy =  [ ... items] 
#  3.4 要将可迭代对象转换为数组,请使用扩展... 而不是 Array.from。const  foo =  document. querySelectorAll ( '.foo' ) const  nodes =  Array. from ( foo) const  nodes =  [ ... foo] 
#  3.5 使用 Array.from 用于类似阵列的对象转换为一个数组。const  arrLike =  {  0 :  'foo' ,  1 :  'bar' ,  2 :  'baz' ,  length:  3  } const  arr =  Array . prototype. slice . call ( arrLike) const  arr =  Array. from ( arrLike) 
#  3.6 使用 Array.from 而不是扩展... 来映射可迭代对象,因为它避免了创建中间数组。const  baz =  [ ... foo] . map ( bar) const  baz =  Array. from ( foo,  bar) 
#  3.7 在数组方法回调中使用 return 语句。如果函数主体由返回 8.2 之后的无副作用的表达式的单个语句组成,则可以省略 return 。[ 1 ,  2 ,  3 ] . map ( ( x )  =>  {   const  y =  x +  1    return  x *  y } ) [ 1 ,  2 ,  3 ] . map ( ( x )  =>  x +  1 ) [ [ 0 ,  1 ] ,  [ 2 ,  3 ] ,  [ 4 ,  5 ] ] . reduce ( ( acc,  item,  index )  =>  {   const  flatten =  acc. concat ( item)  } ) [ [ 0 ,  1 ] ,  [ 2 ,  3 ] ,  [ 4 ,  5 ] ] . reduce ( ( acc,  item,  index )  =>  {   const  flatten =  acc. concat ( item)    return  flatten } ) inbox. filter ( ( msg )  =>  {    const  {  subject,  author }  =  msg   if  ( subject ===  'Mockingbird' )  {      return  author ===  'Harper Lee'    }  else  {      return  false    }  } ) inbox. filter ( ( msg )  =>  {    const  {  subject,  author }  =  msg   if  ( subject ===  'Mockingbird' )  {      return  author ===  'Harper Lee'    }    return  false  } ) 
#  3.8 如果数组有多行,则在打开和关闭数组括号之后使用换行符。const  arr =  [   [ 0 ,  1 ] ,  [ 2 ,  3 ] ,  [ 4 ,  5 ] ,  ] const  objectInArray =  [ {   id:  1 ,  } ,  {   id:  2 ,  } ] const  numberInArray =  [   1 ,  2 ,  ] const  arr =  [ [ 0 ,  1 ] ,  [ 2 ,  3 ] ,  [ 4 ,  5 ] ] const  objectInArray =  [   {      id:  1 ,    } ,    {      id:  2 ,    } ,  ] const  numberInArray =  [   1 ,    2 ,  ] 
#  解构 Destructuring#  4.1 在访问和使用对象的多个属性时,请使用对象分解。为什么?解构使您不必为这些属性创建临时引用。
function  getFullName ( user )  {   const  firstName =  user. firstName   const  lastName =  user. lastName   return  ` ${ firstName}   ${ lastName} `  } function  getFullName ( user )  {   const  {  firstName,  lastName }  =  user   return  ` ${ firstName}   ${ lastName} `  } function  getFullName ( {  firstName,  lastName } )  {   return  ` ${ firstName}   ${ lastName} `  } 
#  4.2 使用数组解构。const  arr =  [ 1 ,  2 ,  3 ,  4 ] const  first =  arr[ 0 ] const  second =  arr[ 1 ] const  [ first,  second]  =  arr
#  4.3 将对象分解用于多个返回值,而不是数组分解。为什么?您可以随时间添加新属性或更改事物顺序,而不会中断呼叫站点。
function  processInput ( input )  {      return  [ left,  right,  top,  bottom]  } const  [ left,  __,  top]  =  processInput ( input) function  processInput ( input )  {      return  {  left,  right,  top,  bottom }  } const  {  left,  top }  =  processInput ( input) 
#  5 字符串 Strings#  5.1 '' 对字符串使用单引号。const  name =  "Capt. Janeway" const  name =  ` Capt. Janeway ` const  name =  'Capt. Janeway' 
#  5.2 导致该行超过 100 个字符的字符串不应使用字符串连接跨多行写入。为什么?破碎的字符串很痛苦,使代码难以搜索。
const  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.' const  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.'  const  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.' 
#  5.3 以编程方式构建字符串时,请使用模板字符串而不是串联。为什么?模板字符串为您提供了清晰易懂的语法,并带有适当的换行符和字符串插值功能。
function  sayHi ( name )  {   return  'How are you, '  +  name +  '?'  } function  sayHi ( name )  {   return  [ 'How are you, ' ,  name,  '?' ] . join ( )  } function  sayHi ( name )  {   return  ` How are you,  ${  name } ? `  } function  sayHi ( name )  {   return  ` How are you,  ${ name} ? `  } 
#  5.4 切勿 eval () 在字符串上使用,它会打开太多漏洞。#  5.5 不要不必要地转义字符串中的字符。为什么?反斜杠会损害可读性,因此仅在必要时才应使用反斜杠。
const  foo =  '\'this\' \i\s \"quoted\"' const  foo =  '\'this\' is "quoted"' const  foo =  ` my name is ' ${ name} ' ` 
#  6 方法 Functions#  6.1 用命名函数表达式而不是函数声明。为什么?悬挂了函数声明,这意味着在文件中定义函数之前很容易 - 太容易 - 对其进行引用。这会损害可读性和可维护性。如果发现函数的定义足够大或过于复杂,以至于妨碍了对文件其余部分的理解,那么也许是时候将其提取到自己的模块中了!无论是否从包含变量中推断出名称,都不要忘记为表达式明确命名(这在现代浏览器中或使用 Babel 等编译器时通常是这种情况)。这消除了有关错误的调用堆栈的任何假设。
function  foo ( )  {    } const  foo  =  function  ( )  {    } const  short  =  function  longUniqueMoreDescriptiveLexicalFoo ( )  {    } 
#  6.2 将立即调用的函数表达式包装在括号中为什么?立即调用的函数表达式是一个单元 - 将其及其包装的调用 paren 封装在 parens 中,以整洁的方式表示出来。请注意,在一个无处不在的模块的世界中,几乎不需要 IIFE。
( function  ( )  {   console. log ( 'Welcome to the Internet. Please follow me.' )  } ( ) ) 
#  6.3 从不在非功能块(声明一个函数 if,while 等等)。而是将函数分配给变量。浏览器将允许您执行此操作,但是它们都以不同的方式解释它,这是个坏消息。#  6.4 注意: ECMA-262 将 a 定义 block 为语句列表。函数声明不是语句。if  ( currentUser)  {   function  test ( )  {      console. log ( 'Nope.' )    }  } let  testif  ( currentUser)  {   test  =  ( )  =>  {      console. log ( 'Yup.' )    }  } 
#  6.5 永远不要命名参数 arguments。这将优先于 arguments 分配给每个功能范围的对象。function  foo ( name,  options,  arguments )  {    } function  foo ( name,  options,  args )  {    } 
#  6.6 从不使用 arguments,... 而是改用 rest 语法。为什么?... 明确说明您要提取的参数。另外,其余参数是一个实际的 Array,而不仅仅是 like 这样的 Array arguments。
function  concatenateAll ( )  {   const  args =  Array . prototype. slice . call ( arguments)    return  args. join ( '' )  } function  concatenateAll ( ... args)  {   return  args. join ( '' )  } 
#  6.7 使用默认参数语法而不是对函数参数进行突变。function  handleThings ( opts )  {            opts =  opts ||  { }     } function  handleThings ( opts )  {   if  ( opts ===  void  0 )  {      opts =  { }    }     } function  handleThings ( opts =  { }  )  {    } 
#  6.8 避免使用默认参数的副作用。为什么?他们对此感到困惑。
var  b =  1 function  count ( a =  b++  )  {   console. log ( a)  } count ( )   count ( )   count ( 3 )  count ( )   
#  6.9 始终将默认参数放在最后。function  handleThings ( opts =  { } ,  name )  {    } function  handleThings ( name,  opts =  { }  )  {    } 
#  6.10 切勿使用 Function 构造函数创建新函数。为什么?以这种方式创建函数的评估字符串类似于 eval (),这将打开漏洞。
var  add =  new  Function ( 'a' ,  'b' ,  'return a + b' ) var  subtract =  Function ( 'a' ,  'b' ,  'return a - b' ) 
#  6.11 功能签名中的间距。为什么?一致性很好,添加或删除名称时不必添加或删除空格。
const  f  =  function ( ) { } const  g  =  function  ( ) { } const  h  =  function ( )  { } const  x  =  function  ( )  { } const  y  =  function  a ( )  { } 
#  6.12 请勿更改参数。为什么?操纵作为参数传入的对象可能会在原始调用方中导致不必要的变量副作用。
function  f1 ( obj )  {   obj. key =  1  } function  f2 ( obj )  {   const  key =  Object . prototype. hasOwnProperty . call ( obj,  'key' )  ?  obj. key :  1  } 
#  6.13 切勿重新分配参数。为什么?重新分配参数可能会导致意外行为,尤其是在访问 arguments 对象时。它还可能导致优化问题,尤其是在 V8 中。
function  f1 ( a )  {   a =  1     } function  f2 ( a )  {   if  ( ! a)  {  a =  1  }     } function  f3 ( a )  {   const  b =  a ||  1     } function  f4 ( a =  1  )  {    } 
#  6.14 优先使用散布运算符... 来调用可变参数函数。为什么?它更干净,您无需提供上下文,也无法轻松地 new 与组合 apply。
const  x =  [ 1 ,  2 ,  3 ,  4 ,  5 ] console. log . apply ( console,  x)  const  x =  [ 1 ,  2 ,  3 ,  4 ,  5 ] console. log ( ... x)  new  ( Function . prototype. bind . apply ( Date,  [ null ,  2016 ,  8 ,  5 ] ) ) new  Date ( ... [ 2016 ,  8 ,  5 ] ) 
#  6.15 具有多行签名或调用的函数应像本指南中的其他所有多行列表一样缩进:每个项目单独一行,最后一个项目后跟逗号。function  foo ( bar,               baz,               quux)  {     } function  foo (   bar,     baz,    quux,  )  {    } console. log ( foo,    bar,    baz)  console. log (    foo,    bar,    baz,  ) 
#  7 方法 Functions#  7.1 当您必须使用匿名函数时(如传递内联回调时),请使用箭头函数符号。为什么?它创建函数的版本,该版本在的上下文中执行,this 通常是您想要的,并且语法更简洁。
为什么不?如果您有一个相当复杂的函数,则可以将该逻辑移到它自己的命名函数表达式中。
[ 1 ,  2 ,  3 ] . map ( function  ( x )  {   const  y =  x +  1    return  x *  y } ) [ 1 ,  2 ,  3 ] . map ( ( x )  =>  {   const  y =  x +  1    return  x *  y } ) 
#  7.2 如果函数主体由返回无副作用的表达式的单个语句组成,则省略花括号并使用隐式返回。否则,请保留括号并使用 return 语句。为什么?语法糖。将多个功能链接在一起时,它读起来很好。
[ 1 ,  2 ,  3 ] . map ( ( number )  =>  {   const  nextNumber =  number +  1    ` A string containing the  ${ nextNumber} . `  } ) [ 1 ,  2 ,  3 ] . map ( ( number )  =>  ` A string containing the  ${ number +  1 } . ` ) [ 1 ,  2 ,  3 ] . map ( ( number )  =>  {   const  nextNumber =  number +  1    return  ` A string containing the  ${ nextNumber} . `  } ) [ 1 ,  2 ,  3 ] . map ( ( number,  index )  =>  ( {   [ index] :  number,  } ) ) function  foo ( callback )  {   const  val =  callback ( )    if  ( val ===  true )  {         }  } let  bool =  false foo ( ( )  =>  bool =  true ) foo ( ( )  =>  {   bool =  true  } ) 
#  7.3 如果表达式跨越多行,请将其括在括号中以提高可读性。为什么?它清楚地显示了函数的开始和结束位置。
[ 'get' ,  'post' ,  'put' ] . map ( ( httpMethod )  =>  Object . prototype. hasOwnProperty . call (     httpMagicObjectWithAVeryLongName,      httpMethod,    )  ) [ 'get' ,  'post' ,  'put' ] . map ( ( httpMethod )  =>  (   Object . prototype. hasOwnProperty . call (      httpMagicObjectWithAVeryLongName,      httpMethod,    )  ) ) 
#  7.4 为了清楚和一致起见,请始终在参数周围加上括号。为什么?添加或删除参数时,最大程度减少差异流失。
[ 1 ,  2 ,  3 ] . map ( x  =>  x *  x) [ 1 ,  2 ,  3 ] . map ( ( x )  =>  x *  x) [ 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! `  ) ) [ 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! `  ) ) [ 1 ,  2 ,  3 ] . map ( x  =>  {   const  y =  x +  1    return  x *  y } ) [ 1 ,  2 ,  3 ] . map ( ( x )  =>  {   const  y =  x +  1    return  x *  y } ) 
#  7.5 避免将箭头函数语法(=>)与比较运算符(<=,>=)混淆。const  itemHeight  =  ( item )  =>  item. height <=  256  ?  item. largeSize :  item. smallSizeconst  itemHeight  =  ( item )  =>  item. height >=  256  ?  item. largeSize :  item. smallSizeconst  itemHeight  =  ( item )  =>  ( item. height <=  256  ?  item. largeSize :  item. smallSize) const  itemHeight  =  ( item )  =>  {   const  {  height,  largeSize,  smallSize }  =  item   return  height <=  256  ?  largeSize :  smallSize } 
#  7.6 使用隐式返回值强制箭头函数体的位置。( foo )  =>   bar  ( foo )  =>   ( bar)  ( foo )  =>  bar ( foo )  =>  ( bar) ( foo )  =>  (    bar ) 
#  8 类和构造函数 Classes & Constructors#  8.1 始终使用 class。避免 prototype 直接操作。为什么?class 语法更简洁,更容易推理。
function  Queue ( contents =  [ ]  )  {   this . queue =  [ ... contents]  } Queue . prototype. pop  =  function  ( )  {   const  value =  this . queue[ 0 ]    this . queue. splice ( 0 ,  1 )    return  value } class  Queue  {   constructor ( contents =  [ ]  )  {      this . queue =  [ ... contents]    }    pop ( )  {      const  value =  this . queue[ 0 ]      this . queue. splice ( 0 ,  1 )      return  value   }  } 
#  8.2 使用 extends 继承。为什么?这是一种继承原型功能而不中断的内置方法 instanceof。
const  inherits =  require ( 'inherits' ) function  PeekableQueue ( contents )  {   Queue . apply ( this ,  contents)  } inherits ( PeekableQueue,  Queue) PeekableQueue . prototype. peek  =  function  ( )  {   return  this . queue[ 0 ]  } class  PeekableQueue  extends  Queue  {   peek ( )  {      return  this . queue[ 0 ]    }  } 
#  8.3 方法可以返回 this 以帮助方法链接。Jedi . prototype. jump  =  function  ( )  {   this . jumping =  true    return  true  } Jedi . prototype. setHeight  =  function  ( height )  {   this . height =  height } const  luke =  new  Jedi ( ) luke. jump ( )   luke. setHeight ( 20 )   class  Jedi  {   jump ( )  {      this . jumping =  true      return  this    }    setHeight ( height )  {      this . height =  height     return  this    }  } const  luke =  new  Jedi ( ) luke. jump ( )    . setHeight ( 20 )  
#  8.4 编写自定义 toString () 方法是可以的,只需确保它可以成功运行并且没有副作用。class  Jedi  {   constructor ( options =  { }  )  {      this . name =  options. name ||  'no name'    }    getName ( )  {      return  this . name   }    toString ( )  {      return  ` Jedi -  ${ this . getName ( ) } `    }  } 
#  8.5 如果未指定类,则类具有默认构造函数。不需要空的构造函数或仅委托给父类的构造函数。class  Jedi  {   constructor ( )  { }    getName ( )  {      return  this . name   }  } class  Rey  extends  Jedi  {   constructor ( ... args)  {      super ( ... args)    }  } class  Rey  extends  Jedi  {   constructor ( ... args)  {      super ( ... args)      this . name =  'Rey'    }  } 
#  8.6 避免重复的班级成员。为什么?重复的类成员声明将默默地选择最后一个 - 几乎可以肯定,重复是一个错误。
class  Foo  {   bar ( )  {  return  1  }    bar ( )  {  return  2  }  } class  Foo  {   bar ( )  {  return  1  }  } class  Foo  {   bar ( )  {  return  2  }  } 
#  8.7 this 除非外部库或框架要求使用特定的非静态方法,否则应使用类方法或将其制成静态方法。作为实例方法,应表明其行为根据接收者的属性而有所不同。class  Foo  {   bar ( )  {      console. log ( 'bar' )    }  } class  Foo  {   bar ( )  {      console. log ( this . bar)    }  } class  Foo  {   constructor ( )  {         }  } class  Foo  {   static  bar ( )  {      console. log ( 'bar' )    }  } 
#  9 Modules#  9.1 始终在非标准模块系统上使用模块(import/export)。您始终可以转换到首选的模块系统。为什么?模块是未来,让我们现在就开始使用未来。
const  AirbnbStyleGuide =  require ( './AirbnbStyleGuide' ) module. exports =  AirbnbStyleGuide. es6 import  AirbnbStyleGuide from  './AirbnbStyleGuide' export  default  AirbnbStyleGuide. es6import  {  es6 }  from  './AirbnbStyleGuide' export  default  es6
#  9.2 不要使用通配符导入。为什么?这可确保您具有单个默认导出。
import  *  as  AirbnbStyleGuide from  './AirbnbStyleGuide' import  AirbnbStyleGuide from  './AirbnbStyleGuide' 
#  9.3 请勿直接从进口货物中出口。为什么?尽管单线简明扼要,但采用一种清晰的导入方式和一种清晰的导出方式可以使事情保持一致。
export  {  es6 as  default  }  from  './AirbnbStyleGuide' import  {  es6 }  from  './AirbnbStyleGuide' export  default  es6
#  9.4 仅从一个位置的路径导入。为什么?具有从同一路径导入的多行可能会使代码难以维护。
import  foo from  'foo' import  {  named1,  named2 }  from  'foo' import  foo,  {  named1,  named2 }  from  'foo' import  foo,  {   named1,    named2,  }  from  'foo' 
#  9.5 不要导出可变绑定。W 为什么?通常应避免突变,尤其是在导出可变绑定时。尽管在某些特殊情况下可能需要使用此技术,但通常只应导出常量引用。
let  foo =  3 export  {  foo } const  foo =  3 export  {  foo } 
#  9.6 在具有单个导出功能的模块中,优先使用默认导出而不是命名导出。为什么?鼓励更多只导出一件事情的文件,这对于可读性和可维护性来说更好。
export  function  foo ( )  { } export  default  function  foo ( )  { } 
#  9.7 将所有 imports 放在非导入语句之上。为什么?由于 imports 被吊起,因此将它们全部保持在顶部可防止出现意外行为。
import  foo from  'foo' foo. init ( )  import  bar from  'bar' import  foo from  'foo' import  bar from  'bar' foo. init ( )  
#  9.8 多行导入应像多行数组和对象文字一样缩进。为什么?花括号与样式指南中的每个其他花括号块遵循相同的缩进规则,尾随逗号也是如此。
import  { longNameA,  longNameB,  longNameC,  longNameD,  longNameE}  from  'path' import  {   longNameA,    longNameB,    longNameC,    longNameD,    longNameE,  }  from  'path' 
#  9.9 在模块 import 语句中禁止 Webpack loader 语法。为什么?由于在导入中使用 Webpack 语法,因此会将代码耦合到模块捆绑器。最好在中使用 loader 语法 webpack.config.js。
import  fooSass from  'css!sass!foo.scss' import  barCss from  'style!css!bar.css' import  fooSass from  'foo.scss' import  barCss from  'bar.css' 
#  9.10 不要包括 eslint JavaScript 文件扩展名:import/extensions为什么?包括扩展将阻止重构,并在每个使用者中不适当地对要导入的模块的实现细节进行硬编码。
import  foo from  './foo.js' import  bar from  './bar.jsx' import  baz from  './baz/index.jsx' import  foo from  './foo' import  bar from  './bar' import  baz from  './baz' 
#  10 迭代器和生成器 Iterators and Generators#  10.1 不要使用迭代器。更喜欢 JavaScript 的高阶函数,而不是像 for-in 或那样的循环 for-of。为什么?这执行了我们不变的规则。处理返回值的纯函数比副作用更容易推论。
使用 map ()/every ()/filter ()/find ()/findIndex ()/reduce ()/some ()/... ... 遍历数组,和 Object.keys ()/ Object.values ()/ Object.entries () 产生数组,以便可以遍历对象。
const  numbers =  [ 1 ,  2 ,  3 ,  4 ,  5 ] let  sum =  0 for  ( let  num of  numbers)  {   sum +=  num } sum ===  15  let  sum =  0 numbers. forEach ( ( num )  =>  {    sum +=  num } ) sum ===  15  const  sum =  numbers. reduce ( ( total,  num )  =>  total +  num,  0 ) sum ===  15  const  increasedByOne =  [ ] for  ( let  i =  0  i <  numbers. length i++ )  {   increasedByOne. push ( numbers[ i]  +  1 )  } const  increasedByOne =  [ ] numbers. forEach ( ( num )  =>  {    increasedByOne. push ( num +  1 )  } ) const  increasedByOne =  numbers. map ( ( num )  =>  num +  1 ) 
#  10.2 现在不要使用生成器。为什么?它们不能很好地移植到 ES5。
#  10.3 如果必须使用生成器,或者不考虑我们的建议,请确保生成器的功能签名间距适当。为什么?function 并且 * 属于相同概念关键字的一部分 - 不是的修饰语 function,function  是唯一的构造,不同于 function。
function  *  foo ( )  {    } const  bar  =  function  *  ( )  {    } const  baz  =  function  * ( )  {    } const  quux  =  function * ( )  {    } function * foo ( )  {    } function  * foo ( )  {    } function * foo ( )  {    } const  wat  =  function * ( )  {    } function *  foo ( )  {    } const  foo  =  function *  ( )  {    } 
#  11 属性 Properties#  11.1 访问属性时,请使用点符号。const  luke =  {   jedi:  true ,    age:  28 ,  } const  isJedi =  luke[ 'jedi' ] const  isJedi =  luke. jedi
#  11.2 使用 [] 变量访问属性时,请使用方括号表示法。const  luke =  {   jedi:  true ,    age:  28 ,  } function  getProp ( prop )  {   return  luke[ prop]  } const  isJedi =  getProp ( 'jedi' ) 
#  11.3 ** 计算指数时,请使用指数运算符。const  binary =  Math. pow ( 2 ,  10 ) const  binary =  2  **  10 
#  12 变量 Variables#  12.1 始终使用 const 或 let 声明变量。不这样做将导致全局变量。我们要避免污染全局名称空间。星球船长警告过我们。superPower =  new  SuperPower ( )  const  superPower =  new  SuperPower ( ) 
#  12.2 每个变量或赋值使用一个 const 或 let 声明。为什么?通过这种方式添加新的变量声明更加容易,而且您不必担心将 a 换成;a , 或引入仅标点符号的 diff。您也可以使用调试器逐步执行每个声明,而不是一次跳过所有声明。
const  items =  getItems ( ) ,     goSportsTeam =  true ,      dragonball =  'z'  const  items =  getItems ( ) ,     goSportsTeam =  true      dragonball =  'z'  const  items =  getItems ( ) const  goSportsTeam =  true const  dragonball =  'z' 
#  12.3 将所有 consts 分组,然后将所有 lets 分组。为什么?以后您可能需要根据先前分配的变量之一分配变量时,这很有用。
let  i,  len,  dragonball,     items =  getItems ( ) ,      goSportsTeam =  true  let  iconst  items =  getItems ( ) let  dragonballconst  goSportsTeam =  true let  lenconst  goSportsTeam =  true const  items =  getItems ( ) let  dragonballlet  ilet  length
#  12.4 在需要的地方分配变量,但将其放置在合理的位置。为什么?let 并且 const 是块作用域而不是函数作用域。
function  checkName ( hasName )  {   const  name =  getName ( )    if  ( hasName ===  'test' )  {      return  false    }    if  ( name ===  'test' )  {      this . setName ( '' )      return  false    }    return  name } function  checkName ( hasName )  {   if  ( hasName ===  'test' )  {      return  false    }    const  name =  getName ( )    if  ( name ===  'test' )  {      this . setName ( '' )      return  false    }    return  name } 
#  12.5 不要链接变量分配。为什么?链接变量分配会创建隐式全局变量。
( function  example ( )  {               let  a =  b =  c =  1  } ( ) ) console. log ( a)   console. log ( b)   console. log ( c)   ( function  example ( )  {   let  a =  1    let  b =  a   let  c =  a } ( ) ) console. log ( a)   console. log ( b)   console. log ( c)   
#  12.6 避免使用一元增减(++,--)。为什么?根据 eslint 文档,一元增量和减量语句会自动插入分号,并且会因应用程序中的值增减而导致静默错误。使用诸如 num += 1 而不是 num++ 或的语句来改变您的值也更具表现力 num ++。禁止一元增量和减量语句还可以防止无意中对值进行预增 / 预减,这也可能导致程序出现意外行为。
const  array =  [ 1 ,  2 ,  3 ] let  num =  1 num++  -- numlet  sum =  0 let  truthyCount =  0 for  ( let  i =  0  i <  array. length i++ )  {   let  value =  array[ i]    sum +=  value   if  ( value)  {      truthyCount++    }  } const  array =  [ 1 ,  2 ,  3 ] let  num =  1 num +=  1  num -=  1  const  sum =  array. reduce ( ( a,  b )  =>  a +  b,  0 ) const  truthyCount =  array. filter ( Boolean) . length
#  12.7 = 在作业之前或之后避免换行。如果您的分配违反 max-len,则将值括在括号中。为什么?周围的换行符 = 可能会使分配的值变得模糊。
const  foo =   superLongLongLongLongLongLongLongLongFunctionName ( )  const  foo  =  'superLongLongLongLongLongLongLongLongString'  const  foo =  (   superLongLongLongLongLongLongLongLongFunctionName ( )  ) const  foo =  'superLongLongLongLongLongLongLongLongString' 
#  12.8 禁止使用未使用的变量。为什么?由于重构不完全,在代码中任何地方声明并没有使用的变量很可能是错误。这样的变量会占用代码中的空间,并可能引起读者的困惑。
var  some_unused_var =  42 var  y =  10 y =  5  var  z =  0 z =  z +  1  function  getX ( x,  y )  {     return  x } function  getXPlusY ( x,  y )  {   return  x +  y } var  x =  1 var  y =  a +  2 alert ( getXPlusY ( x,  y) ) var  {  type,  ... coords }  =  data
#  13 Hoisting#  13.1 var 声明被提升到最接近的封闭函数范围的顶部,而不是赋值。const 和 let 声明被赋予一个所谓的新概念颞盲区(TDZ) 。重要的是要知道为什么 typeof 不再安全。function  example ( )  {   console. log ( notDefined)   } function  example ( )  {   console. log ( declaredButNotAssigned)     var  declaredButNotAssigned =  true  } function  example ( )  {   let  declaredButNotAssigned   console. log ( declaredButNotAssigned)     declaredButNotAssigned =  true  } function  example ( )  {   console. log ( declaredButNotAssigned)     console. log ( typeof  declaredButNotAssigned)     const  declaredButNotAssigned =  true  } 
#  13.2 匿名函数表达式将提升其变量名,而不是函数赋值。function  example ( )  {   console. log ( anonymous)     anonymous ( )     var  anonymous  =  function  ( )  {      console. log ( 'anonymous function expression' )    }  } 
#  13.3 命名函数表达式将提升变量名,而不是函数名或函数体。function  example ( )  {   console. log ( named)     named ( )     superPower ( )     var  named  =  function  superPower ( )  {      console. log ( 'Flying' )    }  } function  example ( )  {   console. log ( named)     named ( )     var  named  =  function  named ( )  {      console. log ( 'named' )    }  } 
#  13.4 函数声明将提升其名称和函数主体。function  example ( )  {   superPower ( )     function  superPower ( )  {      console. log ( 'Flying' )    }  } 
#  14 Comparison Operators & Equality#  14.1 使用 === 和! 过度 和!=。#  14.2 条件语句(例如,if 语句)使用 ToBoolean 抽象方法强制使用强制表达式来评估其表达式,并始终遵循以下简单规则:对象评估为 true 未定义的结果为 false 空评估为假 布尔值的取值为布尔值 如果 + 0,-0 或 NaN,则数字的计算结果为 false,否则为 true 如果为空字符串,则字符串评估为 false'',否则为 true #  14.3 将快捷方式用于布尔值,但对字符串和数字进行显式比较。if  ( isValid ===  true )  {    } if  ( isValid)  {    } if  ( name)  {    } if  ( name !==  '' )  {    } if  ( collection. length)  {    } if  ( collection. length >  0 )  {    } 
#  14.4 使用大括号来创建块 case 和 default 包含词汇声明条款(例如 let,const,function,和 class)。为什么?词法声明在整个 switch 块中都是可见的,但是只有在分配时才进行初始化,只有在 case 到达时才进行初始化。当多个 case 子句尝试定义同一事物时,这会导致问题。
switch  ( foo)  {   case  1 :      let  x =  1      break    case  2 :      const  y =  2      break    case  3 :      function  f ( )  {             }      break    default :      class  C  { }  } switch  ( foo)  {   case  1 :  {      let  x =  1      break    }    case  2 :  {      const  y =  2      break    }    case  3 :  {      function  f ( )  {             }      break    }    case  4 :      bar ( )      break    default :  {      class  C  { }    }  } 
#  14.5 三元数不应嵌套,并且通常是单行表达式。const  foo =  maybe1 >  maybe2  ?  "bar"    :  value1 >  value2 ?  "baz"  :  null  const  maybeNull =  value1 >  value2 ?  'baz'  :  null const  foo =  maybe1 >  maybe2  ?  'bar'    :  maybeNull const  foo =  maybe1 >  maybe2 ?  'bar'  :  maybeNull
#  14.6 避免不必要的三元语句。const  foo =  a ?  a :  bconst  bar =  c ?  true  :  false const  baz =  c ?  false  :  true const  foo =  a ||  bconst  bar =  ! ! cconst  baz =  ! c
#  14.7 混合运算符时,请将其括在括号中。唯一的例外是标准的算术运算符:+,-,和 ** 因为它们的优先级被广义地理解。我们建议将括起来 / 并 * 放在括号中,因为当它们混合使用时,它们的优先级可能会模棱两可。为什么?这提高了可读性并阐明了开发人员的意图。
const  foo =  a &&  b <  0  ||  c >  0  ||  d +  1  ===  0 const  bar =  a **  b -  5  %  dif  ( a ||  b &&  c)  {   return  d } const  bar =  a +  b /  c *  dconst  foo =  ( a &&  b <  0 )  ||  c >  0  ||  ( d +  1  ===  0 ) const  bar =  a **  b -  ( 5  %  d) if  ( a ||  ( b &&  c) )  {   return  d } const  bar =  a +  ( b /  c)  *  d
#  15 Blocks#  15.1 将括号与所有多行块一起使用。if  ( test)   return  false  if  ( test)  return  false if  ( test)  {   return  false  } function  foo ( )  {  return  false  } function  bar ( )  {   return  false  } 
#  15.2 如果您使用带有 if 和的多行块,请与该块的右括号 else 放在 else 同一行 if。if  ( test)  {   thing1 ( )    thing2 ( )  } else  {   thing3 ( )  } if  ( test)  {   thing1 ( )    thing2 ( )  }  else  {   thing3 ( )  } 
#  15.3 如果某个 if 块始终执行一条 return 语句,else 则不需要随后的块。甲 return 在 else if 块中的以下 if 一个包含块 return 可以被分成多个 if 块。function  foo ( )  {   if  ( x)  {      return  x   }  else  {      return  y   }  } function  cats ( )  {   if  ( x)  {      return  x   }  else  if  ( y)  {      return  y   }  } function  dogs ( )  {   if  ( x)  {      return  x   }  else  {      if  ( y)  {        return  y     }    }  } function  foo ( )  {   if  ( x)  {      return  x   }    return  y } function  cats ( )  {   if  ( x)  {      return  x   }    if  ( y)  {      return  y   }  } function  dogs ( x )  {   if  ( x)  {      if  ( z)  {        return  y     }    }  else  {      return  z   }  } 
#  16 Control Statements#  16.1 如果您的控制语句(if,while 等)过长或超过最大行长,则可以将每个(分组的)条件放到新行中。逻辑运算符应从此行开始。为什么?在行的开头要求运算符使运算符保持对齐并遵循类似于方法链接的模式。通过更轻松地从视觉上遵循复杂的逻辑,这也提高了可读性。
if  ( ( foo ===  123  ||  bar ===  'abc' )  &&  doesItLookGoodWhenItBecomesThatLong ( )  &&  isThisReallyHappening ( ) )  {   thing1 ( )  } if  ( foo ===  123  &&   bar ===  'abc' )  {    thing1 ( )  } if  ( foo ===  123   &&  bar ===  'abc' )  {    thing1 ( )  } if  (   foo ===  123  &&    bar ===  'abc'  )  {   thing1 ( )  } if  (   foo ===  123    &&  bar ===  'abc'  )  {   thing1 ( )  } if  (   ( foo ===  123  ||  bar ===  'abc' )    &&  doesItLookGoodWhenItBecomesThatLong ( )    &&  isThisReallyHappening ( )  )  {   thing1 ( )  } if  ( foo ===  123  &&  bar ===  'abc' )  {   thing1 ( )  } 
#  16.2 不要使用选择运算符代替控制语句。! isRunning &&  startRunning ( ) if  ( ! isRunning)  {   startRunning ( )  } 
#  17.1 使用 /** ... */ 的多行注释。function  make ( tag )  {      return  element }  * make() returns a new element  * based on the passed-in tag name  */ function  make ( tag )  {      return  element } 
#  17.2 使用 // 的单行注释。将单行注释放在注释主题上方的换行符上。除非注释位于块的第一行,否则在注释之前放置一个空行。const  active =  true   const  active =  true function  getType ( )  {   console. log ( 'fetching type...' )       const  type =  this . type ||  'no type'    return  type } function  getType ( )  {   console. log ( 'fetching type...' )       const  type =  this . type ||  'no type'    return  type } function  getType ( )  {      const  type =  this . type ||  'no type'    return  type } 
#  17.3 在所有注释的开头加一个空格,以使其易于阅读。const  active =  true const  active =  true  *make() returns a new element  *based on the passed-in tag name  */ function  make ( tag )  {      return  element }  * make() returns a new element  * based on the passed-in tag name  */ function  make ( tag )  {      return  element } 
#  17.5 使用 // FIXME: 注释的问题。class  Calculator  extends  Abacus  {   constructor ( )  {      super ( )           total =  0    }  } 
#  17.6 使用 // TODO: 注释解决问题的办法。class  Calculator  extends  Abacus  {   constructor ( )  {      super ( )           this . total =  0    }  } 
#  18 空格 Whitespace#  18.1 使用设置为 2 个空格的软标签(空格字符)。function  foo ( )  { ∙∙∙∙let  name } function  bar ( )  { ∙let  name } function  baz ( )  { ∙∙let  name } 
#  18.2 在前支架之前放置 1 个空格。function  test ( ) {   console. log ( 'test' )  } function  test ( )  {   console. log ( 'test' )  } dog. set ( 'attr' , {    age:  '1 year' ,    breed:  'Bernese Mountain Dog' ,  } ) dog. set ( 'attr' ,  {    age:  '1 year' ,    breed:  'Bernese Mountain Dog' ,  } ) 
#  18.3 在控制语句(if,while 等)中,在圆括号前放置 1 个空格。在函数调用和声明中,参数列表和函数名称之间不能留空格。if ( isJedi)  {   fight  ( )  } if  ( isJedi)  {   fight ( )  } function  fight  ( )  {   console. log  ( 'Swooosh!' )  } function  fight ( )  {   console. log ( 'Swooosh!' )  } 
#  18.4 用空格隔开运算符。const  x= y+ 5 const  x =  y +  5 
#  18.5 使用单个换行符结束文件。import  {  es6 }  from  './AirbnbStyleGuide'    export  default  es6import  {  es6 }  from  './AirbnbStyleGuide'    export  default  es6↵↵ import  {  es6 }  from  './AirbnbStyleGuide'    export  default  es6↵
#  18.6 制作较长的方法链(两个以上的方法链)时,请使用缩进。使用前导点,强调该行是方法调用,而不是新语句。$ ( '#items' ) . find ( '.selected' ) . highlight ( ) . end ( ) . find ( '.open' ) . updateCount ( ) $ ( '#items' ) .   find ( '.selected' ) .      highlight ( ) .      end ( ) .    find ( '.open' ) .      updateCount ( )  $ ( '#items' )   . find ( '.selected' )      . highlight ( )      . end ( )    . find ( '.open' )      . updateCount ( )  const  leds =  stage. selectAll ( '.led' ) . data ( data) . enter ( ) . append ( 'svg:svg' ) . classed ( 'led' ,  true )     . attr ( 'width' ,  ( radius +  margin)  *  2 ) . append ( 'svg:g' )      . attr ( 'transform' ,  ` translate( ${ radius +  margin} , ${ radius +  margin} ) ` )      . call ( tron. led)  const  leds =  stage. selectAll ( '.led' )     . data ( data)    . enter ( ) . append ( 'svg:svg' )      . classed ( 'led' ,  true )      . attr ( 'width' ,  ( radius +  margin)  *  2 )    . append ( 'svg:g' )      . attr ( 'transform' ,  ` translate( ${ radius +  margin} , ${ radius +  margin} ) ` )      . call ( tron. led)  const  leds =  stage. selectAll ( '.led' ) . data ( data) 
#  18.7 在块之后和下一条语句之前保留空白行。if  ( foo)  {   return  bar } return  bazif  ( foo)  {   return  bar } return  bazconst  obj =  {   foo ( )  {    } ,    bar ( )  {    } ,  } return  objconst  obj =  {   foo ( )  {    } ,    bar ( )  {    } ,  } return  objconst  arr =  [   function  foo ( )  {    } ,    function  bar ( )  {    } ,  ] return  arrconst  arr =  [   function  foo ( )  {    } ,    function  bar ( )  {    } ,  ] return  arr
#  18.8 不要用空行填充块。function  bar ( )  {   console. log ( foo)  } if  ( baz)  {   console. log ( qux)  }  else  {   console. log ( foo)  } class  Foo  {   constructor ( bar )  {      this . bar =  bar   }  } function  bar ( )  {   console. log ( foo)  } if  ( baz)  {   console. log ( qux)  }  else  {   console. log ( foo)  } 
#  18.9 请勿使用多个空行来填充代码。class  Person  {   constructor ( fullName,  email,  birthday )  {      this . fullName =  fullName     this . email =  email     this . setAge ( birthday)    }    setAge ( birthday )  {      const  today =  new  Date ( )      const  age =  this . getAge ( today,  birthday)      this . age =  age   }    getAge ( today,  birthday )  {         }  } class  Person  {   constructor ( fullName,  email,  birthday )  {      this . fullName =  fullName     this . email =  email     this . setAge ( birthday)    }    setAge ( birthday )  {      const  today =  new  Date ( )      const  age =  getAge ( today,  birthday)      this . age =  age   }    getAge ( today,  birthday )  {         }  } 
#  18.10 请勿在括号内添加空格。function  bar (  foo  )  {   return  foo } function  bar ( foo )  {   return  foo } if  (  foo )  {   console. log ( foo)  } if  ( foo)  {   console. log ( foo)  } 
#  18.11 请勿在方括号内添加空格。const  foo =  [  1 ,  2 ,  3  ] console. log ( foo[  0  ] )  const  foo =  [ 1 ,  2 ,  3 ] console. log ( foo[ 0 ] )  
#  18.12 在花括号内添加空格。const  foo =  { clark:  'kent' } const  foo =  {  clark:  'kent'  } 
#  18.13 避免使用超过 100 个字符(包括空格)的代码行。注意:根据上述规定,长字符串不受此规则约束,并且不应分解。为什么?这确保了可读性和可维护性。
const  foo =  jsonData &&  jsonData. foo &&  jsonData. foo. bar &&  jsonData. foo. bar. baz &&  jsonData. foo. bar. baz. quux &&  jsonData. foo. bar. baz. quux. xyzzy$. ajax ( {  method:  'POST' ,  url:  'https://airbnb.com/' ,  data:  {  name:  'John'  }  } ) . done ( ( )  =>  console. log ( 'Congratulations!' ) ) . fail ( ( )  =>  console. log ( 'You have failed this city.' ) )  const  foo =  jsonData  &&  jsonData. foo   &&  jsonData. foo. bar   &&  jsonData. foo. bar. baz   &&  jsonData. foo. bar. baz. quux   &&  jsonData. foo. bar. baz. quux. xyzzy $. ajax ( {    method:  'POST' ,    url:  'https://airbnb.com/' ,    data:  {  name:  'John'  } ,  } )   . done ( ( )  =>  console. log ( 'Congratulations!' ) )    . fail ( ( )  =>  console. log ( 'You have failed this city.' ) )  
#  18.14 在同一行中的一个打开的块令牌和下一个令牌之间,要求保持一致的间距。该规则还强制在同一行上的封闭块令牌和先前令牌内保持一致的间距。function  foo ( )  { return  true } if  ( foo)  {  bar =  0 } function  foo ( )  {  return  true  } if  ( foo)  {  bar =  0  } 
#  18.15 避免在逗号前加空格,并在逗号后加空格。```javascript`
// good
## 18.16 在计算的属性括号内强制使用间距。
```javascript
// bad
obj[foo ]
obj[ 'foo']
var x = {[ b ]: a}
obj[foo[ bar ]]
// good
obj[foo]
obj['foo']
var x = { [b]: a }
obj[foo[bar]]
#  18.17 避免在函数及其调用之间留空格。#  18.18 强制在对象文字属性中的键和值之间保持间距。var  obj =  {  foo :  42  } var  obj2 =  {  foo: 42  } var  obj =  {  foo:  42  } 
#  18.19 避免在行尾使用空格。#  18.20 避免出现多个空行,仅在文件末尾允许一个换行符,并在文件开始时避免换行符。var  x =  1 var  y =  2 var  x =  1 var  y =  2 var  x =  1 var  y =  2 var  x =  1 var  y =  2 
#  19 逗号 Commas#  19.1 主要逗号:Nope。const  story =  [     once   ,  upon   ,  aTime ] const  story =  [   once,    upon,    aTime,  ] const  hero =  {     firstName:  'Ada'    ,  lastName:  'Lovelace'    ,  birthYear:  1815    ,  superPower:  'computers'  } const  hero =  {   firstName:  'Ada' ,    lastName:  'Lovelace' ,    birthYear:  1815 ,    superPower:  'computers' ,  } 
#  19.2 其他尾随逗号: Yup。为什么?这将导致更干净的 git diff。同样,像 Babel 这样的编译器也将删除已编译代码中的其他尾部逗号,这意味着您不必担心传统浏览器中的尾部逗号问题 。
const  hero =  {      firstName:  'Florence' ,  -     lastName:  'Nightingale' +     lastName:  'Nightingale' , +     inventorOf:  [ 'coxcomb chart' ,  'modern nursing' ] } const  hero =  {      firstName:  'Florence' ,       lastName:  'Nightingale' ,  +     inventorOf:  [ 'coxcomb chart' ,  'modern nursing' ] , } const  hero =  {   firstName:  'Dana' ,    lastName:  'Scully'  } const  heroes =  [   'Batman' ,    'Superman'  ] const  hero =  {   firstName:  'Dana' ,    lastName:  'Scully' ,  } const  heroes =  [   'Batman' ,    'Superman' ,  ] function  createHero (   firstName,     lastName,    inventorOf )  {    } function  createHero (   firstName,     lastName,    inventorOf,  )  {    } function  createHero (   firstName,     lastName,    inventorOf,    ... heroArgs )  {    } createHero (   firstName,    lastName,    inventorOf ) createHero (   firstName,    lastName,    inventorOf,  ) createHero (   firstName,    lastName,    inventorOf,    ... heroArgs ) 
#  20 分号 Semicolons#  20.1 Yup。为什么?当 JavaScript 遇到没有分号的换行符时,它将使用称为自动分号插入的一组规则来确定是否应将该换行符视为语句的结尾,并(如其名称所示)将分号放入您的如果这样的话,在换行符之前输入代码。但是,ASI 包含一些异常行为,如果 JavaScript 错误地解释了换行符,则代码将中断。随着新功能成为 JavaScript 的一部分,这些规则将变得更加复杂。明确终止您的语句并配置短毛猫以捕获缺少的分号将有助于防止您遇到问题。
const  luke =  { } const  leia =  { } [ luke,  leia] . forEach ( ( jedi )  =>  jedi. father =  'vader' ) const  reaction =  "No! That’s impossible!" ( async  function  meanwhileOnTheFalcon ( )  {       } ( ) ) function  foo ( )  {   return      'search your feelings, you know it to be foo'  } const  luke =  { } const  leia =  { } [ luke,  leia] . forEach ( ( jedi )  =>  {   jedi. father =  'vader'  } ) const  reaction =  "No! That’s impossible!" ( async  function  meanwhileOnTheFalcon ( )  {       } ( ) ) function  foo ( )  {   return  'search your feelings, you know it to be foo'  } Read more.  
#  21 Type Casting & Coercion#  21.1 在语句的开头执行类型强制。#  21.2 字符串 Stringsconst  totalScore =  new  String ( this . reviewScore)  const  totalScore =  this . reviewScore +  ''  const  totalScore =  this . reviewScore. toString ( )  const  totalScore =  String ( this . reviewScore) 
#  21.3 数字:Number 用于类型转换,并且 parseInt 始终使用基数来解析字符串。const  inputValue =  '4' const  val =  new  Number ( inputValue) const  val =  + inputValueconst  val =  inputValue >>  0 const  val =  parseInt ( inputValue) const  val =  Number ( inputValue) const  val =  parseInt ( inputValue,  10 ) 
#  21.4 如果出于某种原因您正在做一些疯狂的事情,并且 parseInt 是瓶颈,并且出于性能原因而需要使用 Bitshift ,请在注释中说明原因和原因。 * parseInt was the reason my code was slow.  * Bitshifting the String to coerce it to a  * Number made it a lot faster.  */ const  val =  inputValue >>  0 
#  21.5 注意:使用位移操作时要小心。数字表示为 64 位值,但是位移位操作始终返回 32 位整数(source)。对于大于 32 位的整数,位移位会导致意外的行为。讨论。最大的有符号 32 位 Int 是 2,147,483,647:2147483647  >>  0  2147483648  >>  0  2147483649  >>  0  
#  21.6 布尔值const  age =  0 const  hasAge =  new  Boolean ( age) const  hasAge =  Boolean ( age) const  hasAge =  ! ! age
#  22 命名约定 Naming Conventions#  22.1 避免使用单个字母名称。用您的命名来描述。function  q ( )  {    } function  query ( )  {    } 
#  22.2 在命名对象,函数和实例时,请使用 camelCase。const  OBJEcttsssss =  { } const  this_is_my_object =  { } function  c ( )  { } const  thisIsMyObject =  { } function  thisIsMyFunction ( )  { } 
#  22.3 仅在命名构造函数或类时使用 PascalCase。function  user ( options )  {   this . name =  options. name } const  bad =  new  user ( {   name:  'nope' ,  } ) class  User  {   constructor ( options )  {      this . name =  options. name   }  } const  good =  new  User ( {   name:  'yup' ,  } ) 
#  22.4 请勿使用下划线或前划线。为什么?JavaScript 在属性或方法方面没有隐私的概念。尽管下划线是表示 “私有” 的通用约定,但实际上,这些属性是完全公开的,因此是您的公共 API 合同的一部分。该约定可能导致开发人员错误地认为更改不会被视为破坏或不需要测试。tl; dr:如果您希望某些东西是 “私有的”,那么它一定不能明显地存在。
this . __firstName__ =  'Panda' this . firstName_ =  'Panda' this . _firstName =  'Panda' this . firstName =  'Panda' const  firstNames =  new  WeakMap ( ) firstNames. set ( this ,  'Panda' )  
#  22.5 不要保存对的引用 this。使用箭头函数或 Function#bind。function  foo ( )  {   const  self =  this    return  function  ( )  {      console. log ( self)    }  } function  foo ( )  {   const  that =  this    return  function  ( )  {      console. log ( that)    }  } function  foo ( )  {   return  ( )  =>  {      console. log ( this )    }  } 
#  22.6 基本文件名应与默认导出文件名完全匹配。class  CheckBox  {    } export  default  CheckBoxexport  default  function  fortyTwo ( )  {  return  42  } export  default  function  insideDirectory ( )  { } import  CheckBox from  './checkBox'  import  FortyTwo from  './FortyTwo'  import  InsideDirectory from  './InsideDirectory'  import  CheckBox from  './check_box'  import  forty_two from  './forty_two'  import  inside_directory from  './inside_directory'  import  index from  './inside_directory/index'  import  insideDirectory from  './insideDirectory/index'  import  CheckBox from  './CheckBox'  import  fortyTwo from  './fortyTwo'  import  insideDirectory from  './insideDirectory'  
#  22.7 导出默认功能时,请使用 camelCase。文件名应与函数名称相同。function  makeStyleGuide ( )  {    } export  default  makeStyleGuide
#  22.8 在导出构造函数 / 类 / 单例 / 函数库 / 裸对象时使用 PascalCase。const  AirbnbStyleGuide =  {   es6:  {    } ,  } export  default  AirbnbStyleGuide
#  22.9 首字母缩写词和首字母缩写应始终全部大写或全部小写。为什么?名称是为了提高可读性,而不是为了安抚计算机算法。
import  SmsContainer from  './containers/SmsContainer' const  HttpRequests =  [    ] import  SMSContainer from  './containers/SMSContainer' const  HTTPRequests =  [    ] const  httpRequests =  [    ] import  TextMessageContainer from  './containers/TextMessageContainer' const  requests =  [    ] 
#  22.10 您可以选择仅在以下情况下将常量大写:(1)已导出,(2)是一个 const(不能重新分配),并且(3)程序员可以相信它(及其嵌套属性)永不更改。为什么?这是一个辅助工具,可在程序员不确定变量是否会发生变化的情况下提供帮助。UPPERCASE_VARIABLES 让程序员知道他们可以信任变量(及其属性)不变。
那所有 const 变量呢?- 这是不必要的,因此大写不应用于文件中的常量。但是,应将其用于导出的常量。 导出的对象呢?- 在导出的顶层使用大写字母(例如 EXPORTED_OBJECT.key),并保持所有嵌套属性不变。 const  PRIVATE_VARIABLE  =  'should not be unnecessarily uppercased within a file' export  const  THING_TO_BE_CHANGED  =  'should obviously not be uppercased' export  let  REASSIGNABLE_VARIABLE  =  'do not use let with uppercase variables' export  const  apiKey =  'SOMEKEY' export  const  API_KEY  =  'SOMEKEY' export  const  MAPPING  =  {   KEY :  'value'  } export  const  MAPPING  =  {   key:  'value'  } 
#  23 存取器 Accessors#  23.1 不需要属性的访问器功能。#  23.2 请勿使用 JavaScript getter /setter,因为它们会导致意外的副作用,并且更难以测试,维护和推论。相反,如果您确实使访问器函数,请使用 getVal () 和 setVal ('hello')。class  Dragon  {   get  age ( )  {         }    set  age ( value )  {         }  } class  Dragon  {   getAge ( )  {         }    setAge ( value )  {         }  } 
#  23.3 如果属性 / 方法是 a boolean,请使用 isVal () 或 hasVal ()。if  ( ! dragon. age ( ) )  {   return  false  } if  ( ! dragon. hasAge ( ) )  {   return  false  } 
#  23.4 可以创建 get () 和 set () 运行,但要保持一致。class  Jedi  {   constructor ( options =  { }  )  {      const  lightsaber =  options. lightsaber ||  'blue'      this . set ( 'lightsaber' ,  lightsaber)    }    set ( key,  val)  {      this [ key]  =  val   }    get ( key)  {      return  this [ key]    }  } 
#  24 Events#  24.1 在将数据有效负载附加到事件(无论是 DOM 事件还是诸如 Backbone 事件之类的更专有的东西)时,请传递对象文字(也称为 “哈希”)而不是原始值。这允许后续的参与者将更多数据添加到事件有效负载,而无需查找和更新事件的每个处理程序。例如,instead of$ ( this ) . trigger ( 'listingUpdated' ,  listing. id) $ ( this ) . on ( 'listingUpdated' ,  ( e,  listingID )  =>  {    } ) prefer:  $ ( this ) . trigger ( 'listingUpdated' ,  {  listingID:  listing. id } ) $ ( this ) . on ( 'listingUpdated' ,  ( e,  data )  =>  {    } ) 
#  25 jQuery#  25.1 用前缀 jQuery 对象变量 $。const  sidebar =  $ ( '.sidebar' ) const  $sidebar =  $ ( '.sidebar' ) const  $sidebarBtn =  $ ( '.sidebar-btn' ) 
#  25.2 缓存 jQuery 查询。function  setSidebar ( )  {   $ ( '.sidebar' ) . hide ( )       $ ( '.sidebar' ) . css ( {      'background-color' :  'pink' ,    } )  } function  setSidebar ( )  {   const  $sidebar =  $ ( '.sidebar' )    $sidebar. hide ( )       $sidebar. css ( {      'background-color' :  'pink' ,    } )  } 
#  25.4 使用 find 与范围的 jQuery 对象的查询。$ ( 'ul' ,  '.sidebar' ) . hide ( ) $ ( '.sidebar' ) . find ( 'ul' ) . hide ( ) $ ( '.sidebar ul' ) . hide ( ) $ ( '.sidebar > ul' ) . hide ( ) $sidebar. find ( 'ul' ) . hide ( )  
#  26 ECMAScript 5 兼容性 ECMAScript 5 Compatibility#  26.1 请参阅 Kangax  的 ES5 兼容性表 。#  27 Standard Library该标准库 包含了实用程序在功能上打破,但仍遗留原因。
#  27.1 使用 Number.isNaN 代替 global isNaN。为什么?全局将 isNaN 非数字强制转换为数字,对于任何强制为 NaN 的值,返回 true。如果需要此行为,请使其明确。
isNaN ( '1.2' )  isNaN ( '1.2.3' )  Number. isNaN ( '1.2.3' )   Number. isNaN ( Number ( '1.2.3' ) )   
#  27.2 使用 Number.isFinite 而不是 global isFinite。为什么?全局将 isFinite 非数字强制为数字,对于任何强制为有限数字的值,都返回 true。如果需要此行为,请使其明确。
isFinite ( '2e3' )  Number. isFinite ( '2e3' )   Number. isFinite ( parseInt ( '2e3' ,  10 ) )