javascript-guide.html 204 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086
  1. <!DOCTYPE html>
  2. <html lang="en-US">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width,initial-scale=1">
  6. <title>偶游前端</title>
  7. <meta name="generator" content="VuePress 1.9.7">
  8. <meta name="description" content="">
  9. <link rel="preload" href="/docs/assets/css/0.styles.e901f3ad.css" as="style"><link rel="preload" href="/docs/assets/js/app.9d841bbb.js" as="script"><link rel="preload" href="/docs/assets/js/2.a7c99d38.js" as="script"><link rel="preload" href="/docs/assets/js/22.77e586e0.js" as="script"><link rel="prefetch" href="/docs/assets/js/10.dffec12e.js"><link rel="prefetch" href="/docs/assets/js/11.29345ef4.js"><link rel="prefetch" href="/docs/assets/js/12.d71ff1f2.js"><link rel="prefetch" href="/docs/assets/js/13.eadceca7.js"><link rel="prefetch" href="/docs/assets/js/14.86faea9b.js"><link rel="prefetch" href="/docs/assets/js/15.8cc4ecb6.js"><link rel="prefetch" href="/docs/assets/js/16.e10f6d69.js"><link rel="prefetch" href="/docs/assets/js/17.255d9f5b.js"><link rel="prefetch" href="/docs/assets/js/18.9f1823b8.js"><link rel="prefetch" href="/docs/assets/js/19.03db59c9.js"><link rel="prefetch" href="/docs/assets/js/20.f003980f.js"><link rel="prefetch" href="/docs/assets/js/21.5ec8f90e.js"><link rel="prefetch" href="/docs/assets/js/23.793cee7f.js"><link rel="prefetch" href="/docs/assets/js/24.b9b4a05b.js"><link rel="prefetch" href="/docs/assets/js/25.12ca9a6b.js"><link rel="prefetch" href="/docs/assets/js/3.de84d37d.js"><link rel="prefetch" href="/docs/assets/js/4.47824499.js"><link rel="prefetch" href="/docs/assets/js/5.bd819ce0.js"><link rel="prefetch" href="/docs/assets/js/6.dfb8683d.js"><link rel="prefetch" href="/docs/assets/js/7.0e5538c2.js"><link rel="prefetch" href="/docs/assets/js/8.d3104372.js"><link rel="prefetch" href="/docs/assets/js/9.f4b68565.js">
  10. <link rel="stylesheet" href="/docs/assets/css/0.styles.e901f3ad.css">
  11. </head>
  12. <body>
  13. <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/docs/" class="home-link router-link-active"><!----> <span class="site-name">偶游前端</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <!----></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><!----> <ul class="sidebar-links"><li><a href="/docs/" aria-current="page" class="sidebar-link">偶游前端(冯垣玮)</a></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading"><span>项目</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/docs/currentProgram/funfet.html" class="sidebar-link">智能鞋官网</a></li><li><a href="/docs/currentProgram/guide.html" class="sidebar-link">智能鞋落地页</a></li><li><a href="/docs/currentProgram/uni-app-pro.html" class="sidebar-link">智能鞋小程序商城</a></li><li><a href="/docs/currentProgram/customerService.html" class="sidebar-link">智能鞋客服系统</a></li><li><a href="/docs/currentProgram/tank.html" class="sidebar-link">坦克专题</a></li><li><a href="/docs/currentProgram/hiydMini.html" class="sidebar-link">hi运动教练小程序</a></li><li><a href="/docs/currentProgram/hiydShop.html" class="sidebar-link">hi运动商城</a></li><li><a href="/docs/currentProgram/webGame.html" class="sidebar-link">多玩游戏大厅</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><p>原文: https://github.com/ecomfe/spec/blob/master/javascript-style-guide.md</p> <p>注:部分规范有删改</p> <h1 id="javascript编码规范"><a href="#javascript编码规范" class="header-anchor">#</a> JavaScript编码规范</h1> <p><a href="#user-content-1-%E5%89%8D%E8%A8%80">1 前言</a></p> <p><a href="#user-content-2-%E4%BB%A3%E7%A0%81%E9%A3%8E%E6%A0%BC">2 代码风格</a></p> <p><a href="#user-content-21-%E6%96%87%E4%BB%B6">2.1 文件</a></p> <p><a href="#user-content-22-%E7%BB%93%E6%9E%84">2.2 结构</a></p> <p><a href="#user-content-221-%E7%BC%A9%E8%BF%9B">2.2.1 缩进</a></p> <p><a href="#user-content-222-%E7%A9%BA%E6%A0%BC">2.2.2 空格</a></p> <p><a href="#user-content-223-%E6%8D%A2%E8%A1%8C">2.2.3 换行</a></p> <p><a href="#user-content-224-%E8%AF%AD%E5%8F%A5">2.2.4 语句</a></p> <p><a href="#user-content-23-%E5%91%BD%E5%90%8D">2.3 命名</a></p> <p><a href="#user-content-24-%E6%B3%A8%E9%87%8A">2.4 注释</a></p> <p><a href="#user-content-241-%E5%8D%95%E8%A1%8C%E6%B3%A8%E9%87%8A">2.4.1 单行注释</a></p> <p><a href="#user-content-242-%E5%A4%9A%E8%A1%8C%E6%B3%A8%E9%87%8A">2.4.2 多行注释</a></p> <p><a href="#user-content-243-%E6%96%87%E6%A1%A3%E5%8C%96%E6%B3%A8%E9%87%8A">2.4.3 文档化注释</a></p> <p><a href="#user-content-244-%E7%B1%BB%E5%9E%8B%E5%AE%9A%E4%B9%89">2.4.4 类型定义</a></p> <p><a href="#user-content-245-%E6%96%87%E4%BB%B6%E6%B3%A8%E9%87%8A">2.4.5 文件注释</a></p> <p><a href="#user-content-246-%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4%E6%B3%A8%E9%87%8A">2.4.6 命名空间注释</a></p> <p><a href="#user-content-247-%E7%B1%BB%E6%B3%A8%E9%87%8A">2.4.7 类注释</a></p> <p><a href="#user-content-248-%E5%87%BD%E6%95%B0/%E6%96%B9%E6%B3%95%E6%B3%A8%E9%87%8A">2.4.8 函数/方法注释</a></p> <p><a href="#user-content-249-%E4%BA%8B%E4%BB%B6%E6%B3%A8%E9%87%8A">2.4.9 事件注释</a></p> <p><a href="#user-content-2410-%E5%B8%B8%E9%87%8F%E6%B3%A8%E9%87%8A">2.4.10 常量注释</a></p> <p><a href="#user-content-2411-%E5%A4%8D%E6%9D%82%E7%B1%BB%E5%9E%8B%E6%B3%A8%E9%87%8A">2.4.11 复杂类型注释</a></p> <p><a href="#user-content-2413-%E7%BB%86%E8%8A%82%E6%B3%A8%E9%87%8A">2.4.12 细节注释</a></p> <p><a href="#user-content-3-%E8%AF%AD%E8%A8%80%E7%89%B9%E6%80%A7">3 语言特性</a></p> <p><a href="#user-content-31-%E5%8F%98%E9%87%8F">3.1 变量</a></p> <p><a href="#user-content-32-%E6%9D%A1%E4%BB%B6">3.2 条件</a></p> <p><a href="#user-content-33-%E5%BE%AA%E7%8E%AF">3.3 循环</a></p> <p><a href="#user-content-34-%E7%B1%BB%E5%9E%8B">3.4 类型</a></p> <p><a href="#user-content-341-%E7%B1%BB%E5%9E%8B%E6%A3%80%E6%B5%8B">3.4.1 类型检测</a></p> <p><a href="#user-content-342-%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2">3.4.2 类型转换</a></p> <p><a href="#user-content-35-%E5%AD%97%E7%AC%A6%E4%B8%B2">3.5 字符串</a></p> <p><a href="#user-content-36-%E5%AF%B9%E8%B1%A1">3.6 对象</a></p> <p><a href="#user-content-37-%E6%95%B0%E7%BB%84">3.7 数组</a></p> <p><a href="#user-content-38-%E5%87%BD%E6%95%B0">3.8 函数</a></p> <p><a href="#user-content-381-%E5%87%BD%E6%95%B0%E9%95%BF%E5%BA%A6">3.8.1 函数长度</a></p> <p><a href="#user-content-382-%E5%8F%82%E6%95%B0%E8%AE%BE%E8%AE%A1">3.8.2 参数设计</a></p> <p><a href="#user-content-383-%E9%97%AD%E5%8C%85">3.8.3 闭包</a></p> <p><a href="#user-content-384-%E7%A9%BA%E5%87%BD%E6%95%B0">3.8.4 空函数</a></p> <p><a href="#user-content-39-%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1">3.9 面向对象</a></p> <p><a href="#user-content-310-%E5%8A%A8%E6%80%81%E7%89%B9%E6%80%A7">3.10 动态特性</a></p> <p><a href="#user-content-3101-eval">3.10.1 eval</a></p> <p><a href="#user-content-3102-%E5%8A%A8%E6%80%81%E6%89%A7%E8%A1%8C%E4%BB%A3%E7%A0%81">3.10.2 动态执行代码</a></p> <p><a href="#user-content-3103-with">3.10.3 with</a></p> <p><a href="#user-content-3104-delete">3.10.4 delete</a></p> <p><a href="#user-content-3105-%E5%AF%B9%E8%B1%A1%E5%B1%9E%E6%80%A7">3.10.5 对象属性</a></p> <p><a href="#user-content-4-%E6%B5%8F%E8%A7%88%E5%99%A8%E7%8E%AF%E5%A2%83">4 浏览器环境</a></p> <p><a href="#42-dom">4.1 DOM</a></p> <p><a href="#user-content-421-%E5%85%83%E7%B4%A0%E8%8E%B7%E5%8F%96">4.1.1 元素获取</a></p> <p><a href="#user-content-422-%E6%A0%B7%E5%BC%8F%E8%8E%B7%E5%8F%96">4.1.2 样式获取</a></p> <p><a href="#user-content-423-%E6%A0%B7%E5%BC%8F%E8%AE%BE%E7%BD%AE">4.1.3 样式设置</a></p> <p><a href="#user-content-424-dom-%E6%93%8D%E4%BD%9C">4.1.4 DOM 操作</a></p> <p><a href="#user-content-425-dom-%E4%BA%8B%E4%BB%B6">4.1.5 DOM 事件</a></p> <h2 id="_1-前言"><a href="#_1-前言" class="header-anchor">#</a> 1 前言</h2> <p>本文档的目标是使JavaScript代码风格保持一致,容易被理解和被维护。虽然本文档是针对JavaScript设计的,但是在使用各种JavaScript的预编译语言时(如TypeScript等)时,适用的部分也应尽量遵循本文档的约定。</p> <h2 id="_2-代码风格"><a href="#_2-代码风格" class="header-anchor">#</a> 2 代码风格</h2> <h3 id="_2-1-文件"><a href="#_2-1-文件" class="header-anchor">#</a> 2.1 文件</h3> <h5 id="【建议】-javascript-文件使用无-bom-的-utf-8-编码。"><a href="#【建议】-javascript-文件使用无-bom-的-utf-8-编码。" class="header-anchor">#</a> <strong>【建议】</strong> <code>JavaScript</code> 文件使用无 <code>BOM</code> 的 <code>UTF-8</code> 编码。</h5> <p>解释:</p> <p>UTF-8 编码具有更广泛的适应性。BOM 在使用程序或工具处理文件时可能造成不必要的干扰。</p> <h5 id="【建议】-在文件结尾处-保留一个空行。"><a href="#【建议】-在文件结尾处-保留一个空行。" class="header-anchor">#</a> <strong>【建议】</strong> 在文件结尾处,保留一个空行。</h5> <h3 id="_2-2-结构-【强制】"><a href="#_2-2-结构-【强制】" class="header-anchor">#</a> 2.2 结构**【强制】**</h3> <h4 id="_2-2-1-缩进"><a href="#_2-2-1-缩进" class="header-anchor">#</a> 2.2.1 缩进</h4> <h5 id="【强制】-使用-4-个空格做为一个缩进层级-不允许使用-2-个空格-或-tab-字符。"><a href="#【强制】-使用-4-个空格做为一个缩进层级-不允许使用-2-个空格-或-tab-字符。" class="header-anchor">#</a> <strong>【强制】</strong> 使用 <code>4</code> 个空格做为一个缩进层级,不允许使用 <code>2</code> 个空格 或 <code>tab</code> 字符。</h5> <h5 id="【强制】-switch-下的-case-和-default-必须增加一个缩进层级。"><a href="#【强制】-switch-下的-case-和-default-必须增加一个缩进层级。" class="header-anchor">#</a> <strong>【强制】</strong> <code>switch</code> 下的 <code>case</code> 和 <code>default</code> 必须增加一个缩进层级。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  14. <span class="token keyword">switch</span> <span class="token punctuation">(</span>variable<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  15. <span class="token keyword">case</span> <span class="token string">'1'</span><span class="token operator">:</span>
  16. <span class="token comment">// do...</span>
  17. <span class="token keyword">break</span><span class="token punctuation">;</span>
  18. <span class="token keyword">case</span> <span class="token string">'2'</span><span class="token operator">:</span>
  19. <span class="token comment">// do...</span>
  20. <span class="token keyword">break</span><span class="token punctuation">;</span>
  21. <span class="token keyword">default</span><span class="token operator">:</span>
  22. <span class="token comment">// do...</span>
  23. <span class="token punctuation">}</span>
  24. <span class="token comment">// bad</span>
  25. <span class="token keyword">switch</span> <span class="token punctuation">(</span>variable<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  26. <span class="token keyword">case</span> <span class="token string">'1'</span><span class="token operator">:</span>
  27. <span class="token comment">// do...</span>
  28. <span class="token keyword">break</span><span class="token punctuation">;</span>
  29. <span class="token keyword">case</span> <span class="token string">'2'</span><span class="token operator">:</span>
  30. <span class="token comment">// do...</span>
  31. <span class="token keyword">break</span><span class="token punctuation">;</span>
  32. <span class="token keyword">default</span><span class="token operator">:</span>
  33. <span class="token comment">// do...</span>
  34. <span class="token punctuation">}</span>
  35. </code></pre></div><h4 id="_2-2-2-空格"><a href="#_2-2-2-空格" class="header-anchor">#</a> 2.2.2 空格</h4> <h5 id="【强制】-二元运算符两侧必须有一个空格-一元运算符与操作对象之间不允许有空格。"><a href="#【强制】-二元运算符两侧必须有一个空格-一元运算符与操作对象之间不允许有空格。" class="header-anchor">#</a> <strong>【强制】</strong> 二元运算符两侧必须有一个空格,一元运算符与操作对象之间不允许有空格。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token operator">!</span>arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
  36. a<span class="token operator">++</span><span class="token punctuation">;</span>
  37. a <span class="token operator">=</span> b <span class="token operator">+</span> c<span class="token punctuation">;</span>
  38. </code></pre></div><h5 id="【强制】-用作代码块起始的左花括号-前必须有一个空格。"><a href="#【强制】-用作代码块起始的左花括号-前必须有一个空格。" class="header-anchor">#</a> <strong>【强制】</strong> 用作代码块起始的左花括号 <code>{</code> 前必须有一个空格。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  39. <span class="token keyword">if</span> <span class="token punctuation">(</span>condition<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  40. <span class="token punctuation">}</span>
  41. <span class="token keyword">while</span> <span class="token punctuation">(</span>condition<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  42. <span class="token punctuation">}</span>
  43. <span class="token keyword">function</span> <span class="token function">funcName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  44. <span class="token punctuation">}</span>
  45. <span class="token comment">// bad</span>
  46. <span class="token keyword">if</span> <span class="token punctuation">(</span>condition<span class="token punctuation">)</span><span class="token punctuation">{</span>
  47. <span class="token punctuation">}</span>
  48. <span class="token keyword">while</span> <span class="token punctuation">(</span>condition<span class="token punctuation">)</span><span class="token punctuation">{</span>
  49. <span class="token punctuation">}</span>
  50. <span class="token keyword">function</span> <span class="token function">funcName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
  51. <span class="token punctuation">}</span>
  52. </code></pre></div><h5 id="【强制】-if-else-for-while-function-switch-do-try-catch-finally-关键字后-必须有一个空格。"><a href="#【强制】-if-else-for-while-function-switch-do-try-catch-finally-关键字后-必须有一个空格。" class="header-anchor">#</a> <strong>【强制】</strong> <code>if / else / for / while / function / switch / do / try / catch / finally</code> 关键字后,必须有一个空格。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  53. <span class="token keyword">if</span> <span class="token punctuation">(</span>condition<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  54. <span class="token punctuation">}</span>
  55. <span class="token keyword">while</span> <span class="token punctuation">(</span>condition<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  56. <span class="token punctuation">}</span>
  57. <span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  58. <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  59. <span class="token comment">// bad</span>
  60. <span class="token keyword">if</span><span class="token punctuation">(</span>condition<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  61. <span class="token punctuation">}</span>
  62. <span class="token keyword">while</span><span class="token punctuation">(</span>condition<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  63. <span class="token punctuation">}</span>
  64. <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  65. <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  66. </code></pre></div><h5 id="【强制】-在对象创建时-属性中的-之后必须有空格-之前不允许有空格。"><a href="#【强制】-在对象创建时-属性中的-之后必须有空格-之前不允许有空格。" class="header-anchor">#</a> <strong>【强制】</strong> 在对象创建时,属性中的 <code>:</code> 之后必须有空格,<code>:</code> 之前不允许有空格。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  67. <span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span>
  68. <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
  69. <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span>
  70. <span class="token literal-property property">c</span><span class="token operator">:</span> <span class="token number">3</span>
  71. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  72. <span class="token comment">// bad</span>
  73. <span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span>
  74. <span class="token literal-property property">a</span> <span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
  75. <span class="token literal-property property">b</span><span class="token operator">:</span><span class="token number">2</span><span class="token punctuation">,</span>
  76. <span class="token literal-property property">c</span> <span class="token operator">:</span><span class="token number">3</span>
  77. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  78. </code></pre></div><h5 id="【强制】-函数声明、具名函数表达式、函数调用中-函数名和-之间不允许有空格。"><a href="#【强制】-函数声明、具名函数表达式、函数调用中-函数名和-之间不允许有空格。" class="header-anchor">#</a> <strong>【强制】</strong> 函数声明、具名函数表达式、函数调用中,函数名和 <code>(</code> 之间不允许有空格。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  79. <span class="token keyword">function</span> <span class="token function">funcName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  80. <span class="token punctuation">}</span>
  81. <span class="token keyword">var</span> <span class="token function-variable function">funcName</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">funcName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  82. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  83. <span class="token function">funcName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  84. <span class="token comment">// bad</span>
  85. <span class="token keyword">function</span> <span class="token function">funcName</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  86. <span class="token punctuation">}</span>
  87. <span class="token keyword">var</span> <span class="token function-variable function">funcName</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">funcName</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  88. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  89. <span class="token function">funcName</span> <span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  90. </code></pre></div><h5 id="【强制】-和-前不允许有空格。"><a href="#【强制】-和-前不允许有空格。" class="header-anchor">#</a> <strong>【强制】</strong> <code>,</code> 和 <code>;</code> 前不允许有空格。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  91. <span class="token function">callFunc</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span>
  92. <span class="token comment">// bad</span>
  93. <span class="token function">callFunc</span><span class="token punctuation">(</span>a <span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token punctuation">;</span>
  94. </code></pre></div><h5 id="【强制】-在函数调用、函数声明、括号表达式、属性访问、if-for-while-switch-catch-等语句中-和-内紧贴括号部分不允许有空格。"><a href="#【强制】-在函数调用、函数声明、括号表达式、属性访问、if-for-while-switch-catch-等语句中-和-内紧贴括号部分不允许有空格。" class="header-anchor">#</a> <strong>【强制】</strong> 在函数调用、函数声明、括号表达式、属性访问、<code>if / for / while / switch / catch</code> 等语句中,<code>()</code> 和 <code>[]</code> 内紧贴括号部分不允许有空格。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  95. <span class="token function">callFunc</span><span class="token punctuation">(</span>param1<span class="token punctuation">,</span> param2<span class="token punctuation">,</span> param3<span class="token punctuation">)</span><span class="token punctuation">;</span>
  96. <span class="token function">save</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>list<span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>indexes<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  97. needIncream <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span>variable <span class="token operator">+=</span> increament<span class="token punctuation">)</span><span class="token punctuation">;</span>
  98. <span class="token keyword">if</span> <span class="token punctuation">(</span>num <span class="token operator">&gt;</span> list<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  99. <span class="token punctuation">}</span>
  100. <span class="token keyword">while</span> <span class="token punctuation">(</span>len<span class="token operator">--</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  101. <span class="token punctuation">}</span>
  102. <span class="token comment">// bad</span>
  103. <span class="token function">callFunc</span><span class="token punctuation">(</span> param1<span class="token punctuation">,</span> param2<span class="token punctuation">,</span> param3 <span class="token punctuation">)</span><span class="token punctuation">;</span>
  104. <span class="token function">save</span><span class="token punctuation">(</span> <span class="token keyword">this</span><span class="token punctuation">.</span>list<span class="token punctuation">[</span> <span class="token keyword">this</span><span class="token punctuation">.</span>indexes<span class="token punctuation">[</span> i <span class="token punctuation">]</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
  105. needIncreament <span class="token operator">&amp;&amp;</span> <span class="token punctuation">(</span> variable <span class="token operator">+=</span> increament <span class="token punctuation">)</span><span class="token punctuation">;</span>
  106. <span class="token keyword">if</span> <span class="token punctuation">(</span> num <span class="token operator">&gt;</span> list<span class="token punctuation">.</span>length <span class="token punctuation">)</span> <span class="token punctuation">{</span>
  107. <span class="token punctuation">}</span>
  108. <span class="token keyword">while</span> <span class="token punctuation">(</span> len<span class="token operator">--</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span>
  109. <span class="token punctuation">}</span>
  110. </code></pre></div><h5 id="【强制】-单行声明的数组与对象-如果包含元素-和-内紧贴括号部分不允许包含空格。"><a href="#【强制】-单行声明的数组与对象-如果包含元素-和-内紧贴括号部分不允许包含空格。" class="header-anchor">#</a> <strong>【强制】</strong> 单行声明的数组与对象,如果包含元素,<code>{}</code> 和 <code>[]</code> 内紧贴括号部分不允许包含空格。</h5> <p>解释:</p> <p>声明包含元素的数组与对象,只有当内部元素的形式较为简单时,才允许写在一行。元素复杂的情况,还是应该换行书写。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  111. <span class="token keyword">var</span> arr1 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  112. <span class="token keyword">var</span> arr2 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  113. <span class="token keyword">var</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  114. <span class="token keyword">var</span> obj2 <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'obj'</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  115. <span class="token keyword">var</span> obj3 <span class="token operator">=</span> <span class="token punctuation">{</span>
  116. <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'obj'</span><span class="token punctuation">,</span>
  117. <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">20</span><span class="token punctuation">,</span>
  118. <span class="token literal-property property">sex</span><span class="token operator">:</span> <span class="token number">1</span>
  119. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  120. <span class="token comment">// bad</span>
  121. <span class="token keyword">var</span> arr1 <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">]</span><span class="token punctuation">;</span>
  122. <span class="token keyword">var</span> arr2 <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span> <span class="token punctuation">]</span><span class="token punctuation">;</span>
  123. <span class="token keyword">var</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
  124. <span class="token keyword">var</span> obj2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'obj'</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
  125. <span class="token keyword">var</span> obj3 <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'obj'</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token literal-property property">sex</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  126. </code></pre></div><h5 id="【强制】-行尾不得有多余的空格。"><a href="#【强制】-行尾不得有多余的空格。" class="header-anchor">#</a> <strong>【强制】</strong> 行尾不得有多余的空格。</h5> <h4 id="_2-2-3-换行"><a href="#_2-2-3-换行" class="header-anchor">#</a> 2.2.3 换行</h4> <h5 id="【强制】-每个独立语句结束后必须换行。"><a href="#【强制】-每个独立语句结束后必须换行。" class="header-anchor">#</a> <strong>【强制】</strong> 每个独立语句结束后必须换行。</h5> <h5 id="【强制】-每行不得超过-120-个字符。"><a href="#【强制】-每行不得超过-120-个字符。" class="header-anchor">#</a> <strong>【强制】</strong> 每行不得超过 <code>120</code> 个字符。</h5> <p>解释:</p> <p>超长的不可分割的代码允许例外,比如复杂的正则表达式。长字符串不在例外之列。</p> <h5 id="【强制】-运算符处换行时-运算符必须在新行的行首。"><a href="#【强制】-运算符处换行时-运算符必须在新行的行首。" class="header-anchor">#</a> <strong>【强制】</strong> 运算符处换行时,运算符必须在新行的行首。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  127. <span class="token keyword">if</span> <span class="token punctuation">(</span>user<span class="token punctuation">.</span><span class="token function">isAuthenticated</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  128. <span class="token operator">&amp;&amp;</span> user<span class="token punctuation">.</span><span class="token function">isInRole</span><span class="token punctuation">(</span><span class="token string">'admin'</span><span class="token punctuation">)</span>
  129. <span class="token operator">&amp;&amp;</span> user<span class="token punctuation">.</span><span class="token function">hasAuthority</span><span class="token punctuation">(</span><span class="token string">'add-admin'</span><span class="token punctuation">)</span>
  130. <span class="token operator">||</span> user<span class="token punctuation">.</span><span class="token function">hasAuthority</span><span class="token punctuation">(</span><span class="token string">'delete-admin'</span><span class="token punctuation">)</span>
  131. <span class="token punctuation">)</span> <span class="token punctuation">{</span>
  132. <span class="token comment">// Code</span>
  133. <span class="token punctuation">}</span>
  134. <span class="token keyword">var</span> result <span class="token operator">=</span> number1 <span class="token operator">+</span> number2 <span class="token operator">+</span> number3
  135. <span class="token operator">+</span> number4 <span class="token operator">+</span> number5<span class="token punctuation">;</span>
  136. <span class="token comment">// bad</span>
  137. <span class="token keyword">if</span> <span class="token punctuation">(</span>user<span class="token punctuation">.</span><span class="token function">isAuthenticated</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span>
  138. user<span class="token punctuation">.</span><span class="token function">isInRole</span><span class="token punctuation">(</span><span class="token string">'admin'</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span>
  139. user<span class="token punctuation">.</span><span class="token function">hasAuthority</span><span class="token punctuation">(</span><span class="token string">'add-admin'</span><span class="token punctuation">)</span> <span class="token operator">||</span>
  140. user<span class="token punctuation">.</span><span class="token function">hasAuthority</span><span class="token punctuation">(</span><span class="token string">'delete-admin'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  141. <span class="token comment">// Code</span>
  142. <span class="token punctuation">}</span>
  143. <span class="token keyword">var</span> result <span class="token operator">=</span> number1 <span class="token operator">+</span> number2 <span class="token operator">+</span> number3 <span class="token operator">+</span>
  144. number4 <span class="token operator">+</span> number5<span class="token punctuation">;</span>
  145. </code></pre></div><h5 id="【强制】-在函数声明、函数表达式、函数调用、对象创建、数组创建、for语句等场景中-不允许在-或-前换行。"><a href="#【强制】-在函数声明、函数表达式、函数调用、对象创建、数组创建、for语句等场景中-不允许在-或-前换行。" class="header-anchor">#</a> <strong>【强制】</strong> 在函数声明、函数表达式、函数调用、对象创建、数组创建、for语句等场景中,不允许在 <code>,</code> 或 <code>;</code> 前换行。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  146. <span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span>
  147. <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
  148. <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span>
  149. <span class="token literal-property property">c</span><span class="token operator">:</span> <span class="token number">3</span>
  150. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  151. <span class="token function">foo</span><span class="token punctuation">(</span>
  152. aVeryVeryLongArgument<span class="token punctuation">,</span>
  153. anotherVeryLongArgument<span class="token punctuation">,</span>
  154. callback
  155. <span class="token punctuation">)</span><span class="token punctuation">;</span>
  156. <span class="token comment">// bad</span>
  157. <span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span>
  158. <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span>
  159. <span class="token punctuation">,</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token number">2</span>
  160. <span class="token punctuation">,</span> <span class="token literal-property property">c</span><span class="token operator">:</span> <span class="token number">3</span>
  161. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  162. <span class="token function">foo</span><span class="token punctuation">(</span>
  163. aVeryVeryLongArgument
  164. <span class="token punctuation">,</span> anotherVeryLongArgument
  165. <span class="token punctuation">,</span> callback
  166. <span class="token punctuation">)</span><span class="token punctuation">;</span>
  167. </code></pre></div><h5 id="【建议】-不同行为或逻辑的语句集-使用空行隔开-更易阅读。"><a href="#【建议】-不同行为或逻辑的语句集-使用空行隔开-更易阅读。" class="header-anchor">#</a> <strong>【建议】</strong> 不同行为或逻辑的语句集,使用空行隔开,更易阅读。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// 仅为按逻辑换行的示例,不代表setStyle的最优实现</span>
  168. <span class="token keyword">function</span> <span class="token function">setStyle</span><span class="token punctuation">(</span><span class="token parameter">element<span class="token punctuation">,</span> property<span class="token punctuation">,</span> value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  169. <span class="token keyword">if</span> <span class="token punctuation">(</span>element <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  170. <span class="token keyword">return</span><span class="token punctuation">;</span>
  171. <span class="token punctuation">}</span>
  172. element<span class="token punctuation">.</span>style<span class="token punctuation">[</span>property<span class="token punctuation">]</span> <span class="token operator">=</span> value<span class="token punctuation">;</span>
  173. <span class="token punctuation">}</span>
  174. </code></pre></div><h5 id="【建议】-在语句的行长度超过-120-时-根据逻辑条件合理缩进。"><a href="#【建议】-在语句的行长度超过-120-时-根据逻辑条件合理缩进。" class="header-anchor">#</a> <strong>【建议】</strong> 在语句的行长度超过 <code>120</code> 时,根据逻辑条件合理缩进。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// 较复杂的逻辑条件组合,将每个条件独立一行,逻辑运算符放置在行首进行分隔,或将部分逻辑按逻辑组合进行分隔。</span>
  175. <span class="token comment">// 建议最终将右括号 ) 与左大括号 { 放在独立一行,保证与 if 内语句块能容易视觉辨识。</span>
  176. <span class="token keyword">if</span> <span class="token punctuation">(</span>user<span class="token punctuation">.</span><span class="token function">isAuthenticated</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  177. <span class="token operator">&amp;&amp;</span> user<span class="token punctuation">.</span><span class="token function">isInRole</span><span class="token punctuation">(</span><span class="token string">'admin'</span><span class="token punctuation">)</span>
  178. <span class="token operator">&amp;&amp;</span> user<span class="token punctuation">.</span><span class="token function">hasAuthority</span><span class="token punctuation">(</span><span class="token string">'add-admin'</span><span class="token punctuation">)</span>
  179. <span class="token operator">||</span> user<span class="token punctuation">.</span><span class="token function">hasAuthority</span><span class="token punctuation">(</span><span class="token string">'delete-admin'</span><span class="token punctuation">)</span>
  180. <span class="token punctuation">)</span> <span class="token punctuation">{</span>
  181. <span class="token comment">// Code</span>
  182. <span class="token punctuation">}</span>
  183. <span class="token comment">// 按一定长度截断字符串,并使用 + 运算符进行连接。</span>
  184. <span class="token comment">// 分隔字符串尽量按语义进行,如不要在一个完整的名词中间断开。</span>
  185. <span class="token comment">// 特别的,对于HTML片段的拼接,通过缩进,保持和HTML相同的结构。</span>
  186. <span class="token keyword">var</span> html <span class="token operator">=</span> <span class="token string">''</span> <span class="token comment">// 此处用一个空字符串,以便整个HTML片段都在新行严格对齐</span>
  187. <span class="token operator">+</span> <span class="token string">'&lt;article&gt;'</span>
  188. <span class="token operator">+</span> <span class="token string">'&lt;h1&gt;Title here&lt;/h1&gt;'</span>
  189. <span class="token operator">+</span> <span class="token string">'&lt;p&gt;This is a paragraph&lt;/p&gt;'</span>
  190. <span class="token operator">+</span> <span class="token string">'&lt;footer&gt;Complete&lt;/footer&gt;'</span>
  191. <span class="token operator">+</span> <span class="token string">'&lt;/article&gt;'</span><span class="token punctuation">;</span>
  192. <span class="token comment">// 也可使用数组来进行拼接,相对 + 更容易调整缩进。</span>
  193. <span class="token keyword">var</span> html <span class="token operator">=</span> <span class="token punctuation">[</span>
  194. <span class="token string">'&lt;article&gt;'</span><span class="token punctuation">,</span>
  195. <span class="token string">'&lt;h1&gt;Title here&lt;/h1&gt;'</span><span class="token punctuation">,</span>
  196. <span class="token string">'&lt;p&gt;This is a paragraph&lt;/p&gt;'</span><span class="token punctuation">,</span>
  197. <span class="token string">'&lt;footer&gt;Complete&lt;/footer&gt;'</span><span class="token punctuation">,</span>
  198. <span class="token string">'&lt;/article&gt;'</span>
  199. <span class="token punctuation">]</span><span class="token punctuation">;</span>
  200. html <span class="token operator">=</span> html<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">''</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  201. <span class="token comment">// 当参数过多时,将每个参数独立写在一行上,并将结束的右括号 ) 独立一行。</span>
  202. <span class="token comment">// 所有参数必须增加一个缩进。</span>
  203. <span class="token function">foo</span><span class="token punctuation">(</span>
  204. aVeryVeryLongArgument<span class="token punctuation">,</span>
  205. anotherVeryLongArgument<span class="token punctuation">,</span>
  206. callback
  207. <span class="token punctuation">)</span><span class="token punctuation">;</span>
  208. <span class="token comment">// 也可以按逻辑对参数进行组合。</span>
  209. <span class="token comment">// 最经典的是baidu.format函数,调用时将参数分为“模板”和“数据”两块</span>
  210. baidu<span class="token punctuation">.</span><span class="token function">format</span><span class="token punctuation">(</span>
  211. dateFormatTemplate<span class="token punctuation">,</span>
  212. year<span class="token punctuation">,</span> month<span class="token punctuation">,</span> date<span class="token punctuation">,</span> hour<span class="token punctuation">,</span> minute<span class="token punctuation">,</span> second
  213. <span class="token punctuation">)</span><span class="token punctuation">;</span>
  214. <span class="token comment">// 当函数调用时,如果有一个或以上参数跨越多行,应当每一个参数独立一行。</span>
  215. <span class="token comment">// 这通常出现在匿名函数或者对象初始化等作为参数时,如setTimeout函数等。</span>
  216. <span class="token function">setTimeout</span><span class="token punctuation">(</span>
  217. <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  218. <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">'hello'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  219. <span class="token punctuation">}</span><span class="token punctuation">,</span>
  220. <span class="token number">200</span>
  221. <span class="token punctuation">)</span><span class="token punctuation">;</span>
  222. order<span class="token punctuation">.</span>data<span class="token punctuation">.</span><span class="token function">read</span><span class="token punctuation">(</span>
  223. <span class="token string">'id='</span> <span class="token operator">+</span> me<span class="token punctuation">.</span>model<span class="token punctuation">.</span>id<span class="token punctuation">,</span>
  224. <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  225. me<span class="token punctuation">.</span><span class="token function">attchToModel</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span>
  226. <span class="token function">callback</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  227. <span class="token punctuation">}</span><span class="token punctuation">,</span>
  228. <span class="token number">300</span>
  229. <span class="token punctuation">)</span><span class="token punctuation">;</span>
  230. <span class="token comment">// 链式调用较长时采用缩进进行调整。</span>
  231. <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">'#items'</span><span class="token punctuation">)</span>
  232. <span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">'.selected'</span><span class="token punctuation">)</span>
  233. <span class="token punctuation">.</span><span class="token function">highlight</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  234. <span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  235. <span class="token comment">// 三元运算符由3部分组成,因此其换行应当根据每个部分的长度不同,形成不同的情况。</span>
  236. <span class="token keyword">var</span> result <span class="token operator">=</span> thisIsAVeryVeryLongCondition
  237. <span class="token operator">?</span> resultA <span class="token operator">:</span> resultB<span class="token punctuation">;</span>
  238. <span class="token keyword">var</span> result <span class="token operator">=</span> condition
  239. <span class="token operator">?</span> thisIsAVeryVeryLongResult
  240. <span class="token operator">:</span> resultB<span class="token punctuation">;</span>
  241. <span class="token comment">// 数组和对象初始化的混用,严格按照每个对象的 { 和结束 } 在独立一行的风格书写。</span>
  242. <span class="token keyword">var</span> array <span class="token operator">=</span> <span class="token punctuation">[</span>
  243. <span class="token punctuation">{</span>
  244. <span class="token comment">// ...</span>
  245. <span class="token punctuation">}</span><span class="token punctuation">,</span>
  246. <span class="token punctuation">{</span>
  247. <span class="token comment">// ...</span>
  248. <span class="token punctuation">}</span>
  249. <span class="token punctuation">]</span><span class="token punctuation">;</span>
  250. </code></pre></div><h5 id="【建议】-对于-if-else-、try-catch-finally-等语句-推荐使用在-号后添加一个换行-的风格-使代码层次结构更清晰-阅读性更好。"><a href="#【建议】-对于-if-else-、try-catch-finally-等语句-推荐使用在-号后添加一个换行-的风格-使代码层次结构更清晰-阅读性更好。" class="header-anchor">#</a> <strong>【建议】</strong> 对于 <code>if...else...</code>、<code>try...catch...finally</code> 等语句,推荐使用在 <code>}</code> 号后添加一个换行 的风格,使代码层次结构更清晰,阅读性更好。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">if</span> <span class="token punctuation">(</span>condition<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  251. <span class="token comment">// some statements;</span>
  252. <span class="token punctuation">}</span>
  253. <span class="token keyword">else</span> <span class="token punctuation">{</span>
  254. <span class="token comment">// some statements;</span>
  255. <span class="token punctuation">}</span>
  256. <span class="token keyword">try</span> <span class="token punctuation">{</span>
  257. <span class="token comment">// some statements;</span>
  258. <span class="token punctuation">}</span>
  259. <span class="token keyword">catch</span> <span class="token punctuation">(</span>ex<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  260. <span class="token comment">// some statements;</span>
  261. <span class="token punctuation">}</span>
  262. </code></pre></div><h4 id="_2-2-4-语句"><a href="#_2-2-4-语句" class="header-anchor">#</a> 2.2.4 语句</h4> <h5 id="【强制】-不得省略语句结束的分号。"><a href="#【强制】-不得省略语句结束的分号。" class="header-anchor">#</a> <strong>【强制】</strong> 不得省略语句结束的分号。</h5> <h5 id="【强制】-在-if-else-for-do-while-语句中-即使只有一行-也不得省略块-。"><a href="#【强制】-在-if-else-for-do-while-语句中-即使只有一行-也不得省略块-。" class="header-anchor">#</a> <strong>【强制】</strong> 在 <code>if / else / for / do / while</code> 语句中,即使只有一行,也不得省略块 <code>{...}</code>。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  263. <span class="token keyword">if</span> <span class="token punctuation">(</span>condition<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  264. <span class="token function">callFunc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  265. <span class="token punctuation">}</span>
  266. <span class="token comment">// bad</span>
  267. <span class="token keyword">if</span> <span class="token punctuation">(</span>condition<span class="token punctuation">)</span> <span class="token function">callFunc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  268. <span class="token keyword">if</span> <span class="token punctuation">(</span>condition<span class="token punctuation">)</span>
  269. <span class="token function">callFunc</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  270. </code></pre></div><h5 id="【强制】-函数定义结束不允许添加分号。"><a href="#【强制】-函数定义结束不允许添加分号。" class="header-anchor">#</a> <strong>【强制】</strong> 函数定义结束不允许添加分号。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  271. <span class="token keyword">function</span> <span class="token function">funcName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  272. <span class="token punctuation">}</span>
  273. <span class="token comment">// bad</span>
  274. <span class="token keyword">function</span> <span class="token function">funcName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  275. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  276. <span class="token comment">// 如果是函数表达式,分号是不允许省略的。</span>
  277. <span class="token keyword">var</span> <span class="token function-variable function">funcName</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  278. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  279. </code></pre></div><h5 id="【强制】-iife-必须在函数表达式外添加-非-iife-不得在函数表达式外添加-。"><a href="#【强制】-iife-必须在函数表达式外添加-非-iife-不得在函数表达式外添加-。" class="header-anchor">#</a> <strong>【强制】</strong> <code>IIFE</code> 必须在函数表达式外添加 <code>(</code>,非 <code>IIFE</code> 不得在函数表达式外添加 <code>(</code>。</h5> <p>解释:</p> <p>IIFE = Immediately-Invoked Function Expression.</p> <p>额外的 ( 能够让代码在阅读的一开始就能判断函数是否立即被调用,进而明白接下来代码的用途。而不是一直拖到底部才恍然大悟。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  280. <span class="token keyword">var</span> task <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  281. <span class="token comment">// Code</span>
  282. <span class="token keyword">return</span> result<span class="token punctuation">;</span>
  283. <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  284. <span class="token keyword">var</span> <span class="token function-variable function">func</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  285. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  286. <span class="token comment">// bad</span>
  287. <span class="token keyword">var</span> <span class="token function-variable function">task</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  288. <span class="token comment">// Code</span>
  289. <span class="token keyword">return</span> result<span class="token punctuation">;</span>
  290. <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  291. <span class="token keyword">var</span> func <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  292. <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  293. </code></pre></div><h3 id="_2-3-命名"><a href="#_2-3-命名" class="header-anchor">#</a> 2.3 命名</h3> <h5 id="【强制】-变量-使用-camel命名法。"><a href="#【强制】-变量-使用-camel命名法。" class="header-anchor">#</a> <strong>【强制】</strong> <code>变量</code> 使用 <code>Camel命名法</code>。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">var</span> loadingModules <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  294. </code></pre></div><h5 id="【强制】-常量-使用-全部字母大写-单词间下划线分隔-的命名方式。"><a href="#【强制】-常量-使用-全部字母大写-单词间下划线分隔-的命名方式。" class="header-anchor">#</a> <strong>【强制】</strong> <code>常量</code> 使用 <code>全部字母大写,单词间下划线分隔</code> 的命名方式。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">var</span> <span class="token constant">HTML_ENTITY</span> <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  295. </code></pre></div><h5 id="【强制】-函数-使用-camel命名法。"><a href="#【强制】-函数-使用-camel命名法。" class="header-anchor">#</a> <strong>【强制】</strong> <code>函数</code> 使用 <code>Camel命名法</code>。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">function</span> <span class="token function">stringFormat</span><span class="token punctuation">(</span><span class="token parameter">source</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  296. <span class="token punctuation">}</span>
  297. </code></pre></div><h5 id="【强制】-函数的-参数-使用-camel命名法。"><a href="#【强制】-函数的-参数-使用-camel命名法。" class="header-anchor">#</a> <strong>【强制】</strong> 函数的 <code>参数</code> 使用 <code>Camel命名法</code>。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">function</span> <span class="token function">hear</span><span class="token punctuation">(</span><span class="token parameter">theBells</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  298. <span class="token punctuation">}</span>
  299. </code></pre></div><h5 id="【强制】-类-使用-pascal命名法。"><a href="#【强制】-类-使用-pascal命名法。" class="header-anchor">#</a> <strong>【强制】</strong> <code>类</code> 使用 <code>Pascal命名法</code>。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">function</span> <span class="token function">TextNode</span><span class="token punctuation">(</span><span class="token parameter">options</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  300. <span class="token punctuation">}</span>
  301. </code></pre></div><h5 id="【强制】-类的-方法-属性-使用-camel命名法。"><a href="#【强制】-类的-方法-属性-使用-camel命名法。" class="header-anchor">#</a> <strong>【强制】</strong> 类的 <code>方法 / 属性</code> 使用 <code>Camel命名法</code>。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">function</span> <span class="token function">TextNode</span><span class="token punctuation">(</span><span class="token parameter">value<span class="token punctuation">,</span> engine</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  302. <span class="token keyword">this</span><span class="token punctuation">.</span>value <span class="token operator">=</span> value<span class="token punctuation">;</span>
  303. <span class="token keyword">this</span><span class="token punctuation">.</span>engine <span class="token operator">=</span> engine<span class="token punctuation">;</span>
  304. <span class="token punctuation">}</span>
  305. <span class="token class-name">TextNode</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">clone</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  306. <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span>
  307. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  308. </code></pre></div><h5 id="【强制】-枚举变量-使用-pascal命名法-枚举的属性-使用-全部字母大写-单词间下划线分隔-的命名方式。"><a href="#【强制】-枚举变量-使用-pascal命名法-枚举的属性-使用-全部字母大写-单词间下划线分隔-的命名方式。" class="header-anchor">#</a> <strong>【强制】</strong> <code>枚举变量</code> 使用 <code>Pascal命名法</code>,<code>枚举的属性</code> 使用 <code>全部字母大写,单词间下划线分隔</code> 的命名方式。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">var</span> TargetState <span class="token operator">=</span> <span class="token punctuation">{</span>
  309. <span class="token constant">READING</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
  310. <span class="token constant">READED</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span>
  311. <span class="token constant">APPLIED</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span>
  312. <span class="token constant">READY</span><span class="token operator">:</span> <span class="token number">4</span>
  313. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  314. </code></pre></div><h5 id="【强制】-命名空间-使用-camel命名法。"><a href="#【强制】-命名空间-使用-camel命名法。" class="header-anchor">#</a> <strong>【强制】</strong> <code>命名空间</code> 使用 <code>Camel命名法</code>。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code>equipments<span class="token punctuation">.</span>heavyWeapons <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  315. </code></pre></div><h5 id="【强制】-由多个单词组成的缩写词-在命名中-根据当前命名法和出现的位置-所有字母的大小写与首字母的大小写保持一致。"><a href="#【强制】-由多个单词组成的缩写词-在命名中-根据当前命名法和出现的位置-所有字母的大小写与首字母的大小写保持一致。" class="header-anchor">#</a> <strong>【强制】</strong> 由多个单词组成的缩写词,在命名中,根据当前命名法和出现的位置,所有字母的大小写与首字母的大小写保持一致。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">function</span> <span class="token function">XMLParser</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  316. <span class="token punctuation">}</span>
  317. <span class="token keyword">function</span> <span class="token function">insertHTML</span><span class="token punctuation">(</span><span class="token parameter">element<span class="token punctuation">,</span> html</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  318. <span class="token punctuation">}</span>
  319. <span class="token keyword">var</span> httpRequest <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HTTPRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  320. </code></pre></div><h5 id="【强制】-类名-使用-名词。"><a href="#【强制】-类名-使用-名词。" class="header-anchor">#</a> <strong>【强制】</strong> <code>类名</code> 使用 <code>名词</code>。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">function</span> <span class="token function">Engine</span><span class="token punctuation">(</span><span class="token parameter">options</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  321. <span class="token punctuation">}</span>
  322. </code></pre></div><h5 id="【建议】-函数名-使用-动宾短语。"><a href="#【建议】-函数名-使用-动宾短语。" class="header-anchor">#</a> <strong>【建议】</strong> <code>函数名</code> 使用 <code>动宾短语</code>。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">function</span> <span class="token function">getStyle</span><span class="token punctuation">(</span><span class="token parameter">element</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  323. <span class="token punctuation">}</span>
  324. </code></pre></div><h5 id="【建议】-boolean-类型的变量使用-is-或-has-开头。"><a href="#【建议】-boolean-类型的变量使用-is-或-has-开头。" class="header-anchor">#</a> <strong>【建议】</strong> <code>boolean</code> 类型的变量使用 <code>is</code> 或 <code>has</code> 开头。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">var</span> isReady <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
  325. <span class="token keyword">var</span> hasMoreCommands <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
  326. </code></pre></div><h5 id="【建议】-promise对象-用-动宾短语的进行时-表达。"><a href="#【建议】-promise对象-用-动宾短语的进行时-表达。" class="header-anchor">#</a> <strong>【建议】</strong> <code>Promise对象</code> 用 <code>动宾短语的进行时</code> 表达。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">var</span> loadingData <span class="token operator">=</span> ajax<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">'url'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  327. loadingData<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>callback<span class="token punctuation">)</span><span class="token punctuation">;</span>
  328. </code></pre></div><h3 id="_2-4-注释"><a href="#_2-4-注释" class="header-anchor">#</a> 2.4 注释</h3> <h4 id="_2-4-1-单行注释"><a href="#_2-4-1-单行注释" class="header-anchor">#</a> 2.4.1 单行注释</h4> <h5 id="【强制】-必须独占一行。-后跟一个空格-缩进与下一行被注释说明的代码一致。"><a href="#【强制】-必须独占一行。-后跟一个空格-缩进与下一行被注释说明的代码一致。" class="header-anchor">#</a> <strong>【强制】</strong> 必须独占一行。<code>//</code> 后跟一个空格,缩进与下一行被注释说明的代码一致。</h5> <h4 id="_2-4-2-多行注释"><a href="#_2-4-2-多行注释" class="header-anchor">#</a> 2.4.2 多行注释</h4> <h5 id="【建议】-避免使用-这样的多行注释。有多行注释内容时-使用多个单行注释。"><a href="#【建议】-避免使用-这样的多行注释。有多行注释内容时-使用多个单行注释。" class="header-anchor">#</a> <strong>【建议】</strong> 避免使用 <code>/*...*/</code> 这样的多行注释。有多行注释内容时,使用多个单行注释。</h5> <h4 id="_2-4-3-文档化注释"><a href="#_2-4-3-文档化注释" class="header-anchor">#</a> 2.4.3 文档化注释</h4> <h5 id="【强制】-为了便于代码阅读和自文档化-以下内容必须包含以-形式的块注释中。"><a href="#【强制】-为了便于代码阅读和自文档化-以下内容必须包含以-形式的块注释中。" class="header-anchor">#</a> <strong>【强制】</strong> 为了便于代码阅读和自文档化,以下内容必须包含以 <code>/**...*/</code> 形式的块注释中。</h5> <p>解释:</p> <ol><li>文件</li> <li>namespace</li> <li>类</li> <li>函数或方法</li> <li>类属性</li> <li>事件</li> <li>全局变量</li> <li>常量</li></ol> <h5 id="【强制】-文档注释前必须空一行。"><a href="#【强制】-文档注释前必须空一行。" class="header-anchor">#</a> <strong>【强制】</strong> 文档注释前必须空一行。</h5> <h5 id="【建议】-自文档化的文档说明-what-而不是-how。"><a href="#【建议】-自文档化的文档说明-what-而不是-how。" class="header-anchor">#</a> <strong>【建议】</strong> 自文档化的文档说明 what,而不是 how。</h5> <h4 id="_2-4-4-类型定义"><a href="#_2-4-4-类型定义" class="header-anchor">#</a> 2.4.4 类型定义</h4> <h5 id="【强制】-类型定义都是以-开始-以-结束。"><a href="#【强制】-类型定义都是以-开始-以-结束。" class="header-anchor">#</a> <strong>【强制】</strong> 类型定义都是以<code>{</code>开始, 以<code>}</code>结束。</h5> <p>解释:</p> <p>常用类型如:{string}, {number}, {boolean}, {Object}, {Function}, {RegExp}, {Array}, {Date}。</p> <p>类型不仅局限于内置的类型,也可以是自定义的类型。比如定义了一个类 Developer,就可以使用它来定义一个参数和返回值的类型。</p> <h5 id="【强制】-对于基本类型-string-number-boolean-首字母必须小写。"><a href="#【强制】-对于基本类型-string-number-boolean-首字母必须小写。" class="header-anchor">#</a> <strong>【强制】</strong> 对于基本类型 {string}, {number}, {boolean},首字母必须小写。</h5> <table><thead><tr><th>类型定义</th> <th>语法示例</th> <th>解释</th></tr></thead> <tbody><tr><td>String</td> <td>{string}</td> <td>--</td></tr> <tr><td>Number</td> <td>{number}</td> <td>--</td></tr> <tr><td>Boolean</td> <td>{boolean}</td> <td>--</td></tr> <tr><td>Object</td> <td>{Object}</td> <td>--</td></tr> <tr><td>Function</td> <td>{Function}</td> <td>--</td></tr> <tr><td>RegExp</td> <td>{RegExp}</td> <td>--</td></tr> <tr><td>Array</td> <td>{Array}</td> <td>--</td></tr> <tr><td>Date</td> <td>{Date}</td> <td>--</td></tr> <tr><td>单一类型集合</td> <td>{Array.&lt;string&gt;}</td> <td>string 类型的数组</td></tr> <tr><td>多类型</td> <td>{(number|boolean)}</td> <td>可能是 number 类型, 也可能是 boolean 类型</td></tr> <tr><td>允许为null</td> <td>{?number}</td> <td>可能是 number, 也可能是 null</td></tr> <tr><td>不允许为null</td> <td>{!Object}</td> <td>Object 类型, 但不是 null</td></tr> <tr><td>Function类型</td> <td>{function(number, boolean)}</td> <td>函数, 形参类型</td></tr> <tr><td>Function带返回值</td> <td>{function(number, boolean):string}</td> <td>函数, 形参, 返回值类型</td></tr> <tr><td>参数可选</td> <td>@param {string=} name</td> <td>可选参数, =为类型后缀</td></tr> <tr><td>可变参数</td> <td>@param {...number} args</td> <td>变长参数, ...为类型前缀</td></tr> <tr><td>任意类型</td> <td>{*}</td> <td>任意类型</td></tr> <tr><td>可选任意类型</td> <td>@param {*=} name</td> <td>可选参数,类型不限</td></tr> <tr><td>可变任意类型</td> <td>@param {...*} args</td> <td>变长参数,类型不限</td></tr></tbody></table> <h4 id="_2-4-5-文件注释"><a href="#_2-4-5-文件注释" class="header-anchor">#</a> 2.4.5 文件注释</h4> <h5 id="【强制】-文件顶部必须包含文件注释-用-file-标识文件说明。"><a href="#【强制】-文件顶部必须包含文件注释-用-file-标识文件说明。" class="header-anchor">#</a> <strong>【强制】</strong> 文件顶部必须包含文件注释,用 <code>@file</code> 标识文件说明。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">/**
  329. * @file Describe the file
  330. */</span>
  331. </code></pre></div><h5 id="【建议】-文件注释中可以用-author-标识开发者信息。"><a href="#【建议】-文件注释中可以用-author-标识开发者信息。" class="header-anchor">#</a> <strong>【建议】</strong> 文件注释中可以用 <code>@author</code> 标识开发者信息。</h5> <p>解释:</p> <p>开发者信息能够体现开发人员对文件的贡献,并且能够让遇到问题或希望了解相关信息的人找到维护人。通常情况文件在被创建时标识的是创建者。随着项目的进展,越来越多的人加入,参与这个文件的开发,新的作者应该被加入 <code>@author</code> 标识。</p> <p><code>@author</code> 标识具有多人时,原则是按照 <code>责任</code> 进行排序。通常的说就是如果有问题,就是找第一个人应该比找第二个人有效。比如文件的创建者由于各种原因,模块移交给了其他人或其他团队,后来因为新增需求,其他人在新增代码时,添加 <code>@author</code> 标识应该把自己的名字添加在创建人的前面。</p> <p><code>@author</code> 中的名字不允许被删除。任何劳动成果都应该被尊重。</p> <p>业务项目中,一个文件可能被多人频繁修改,并且每个人的维护时间都可能不会很长,不建议为文件增加 <code>@author</code> 标识。通过版本控制系统追踪变更,按业务逻辑单元确定模块的维护责任人,通过文档与wiki跟踪和查询,是更好的责任管理方式。</p> <p>对于业务逻辑无关的技术型基础项目,特别是开源的公共项目,应使用 <code>@author</code> 标识。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">/**
  332. * @file Describe the file
  333. * @author author-name(mail-name@domain.com)
  334. * author-name2(mail-name2@domain.com)
  335. */</span>
  336. </code></pre></div><h4 id="_2-4-6-命名空间注释"><a href="#_2-4-6-命名空间注释" class="header-anchor">#</a> 2.4.6 命名空间注释</h4> <h5 id="【建议】-命名空间使用-namespace-标识。"><a href="#【建议】-命名空间使用-namespace-标识。" class="header-anchor">#</a> <strong>【建议】</strong> 命名空间使用 <code>@namespace</code> 标识。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">/**
  337. * @namespace
  338. */</span>
  339. <span class="token keyword">var</span> util <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  340. </code></pre></div><h4 id="_2-4-7-类注释"><a href="#_2-4-7-类注释" class="header-anchor">#</a> 2.4.7 类注释</h4> <h5 id="【建议】-使用-class-标记类或构造函数。"><a href="#【建议】-使用-class-标记类或构造函数。" class="header-anchor">#</a> <strong>【建议】</strong> 使用 <code>@class</code> 标记类或构造函数。</h5> <p>解释:</p> <p>对于使用对象 <code>constructor</code> 属性来定义的构造函数,可以使用 <code>@constructor</code> 来标记。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">/**
  341. * 描述
  342. *
  343. * @class
  344. */</span>
  345. <span class="token keyword">function</span> <span class="token function">Developer</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  346. <span class="token comment">// constructor body</span>
  347. <span class="token punctuation">}</span>
  348. </code></pre></div><h5 id="【建议】-使用-extends-标记类的继承信息。"><a href="#【建议】-使用-extends-标记类的继承信息。" class="header-anchor">#</a> <strong>【建议】</strong> 使用 <code>@extends</code> 标记类的继承信息。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">/**
  349. * 描述
  350. *
  351. * @class
  352. * @extends Developer
  353. */</span>
  354. <span class="token keyword">function</span> <span class="token function">Fronteer</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  355. <span class="token function">Developer</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  356. <span class="token comment">// constructor body</span>
  357. <span class="token punctuation">}</span>
  358. util<span class="token punctuation">.</span><span class="token function">inherits</span><span class="token punctuation">(</span>Fronteer<span class="token punctuation">,</span> Developer<span class="token punctuation">)</span><span class="token punctuation">;</span>
  359. </code></pre></div><h5 id="【强制】-使用包装方式扩展类成员时-必须通过-lends-进行重新指向。"><a href="#【强制】-使用包装方式扩展类成员时-必须通过-lends-进行重新指向。" class="header-anchor">#</a> <strong>【强制】</strong> 使用包装方式扩展类成员时, 必须通过 <code>@lends</code> 进行重新指向。</h5> <p>解释:</p> <p>没有 <code>@lends</code> 标记将无法为该类生成包含扩展类成员的文档。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">/**
  360. * 类描述
  361. *
  362. * @class
  363. * @extends Developer
  364. */</span>
  365. <span class="token keyword">function</span> <span class="token function">Fronteer</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  366. <span class="token function">Developer</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  367. <span class="token comment">// constructor body</span>
  368. <span class="token punctuation">}</span>
  369. util<span class="token punctuation">.</span><span class="token function">extend</span><span class="token punctuation">(</span>
  370. <span class="token class-name">Fronteer</span><span class="token punctuation">.</span>prototype<span class="token punctuation">,</span>
  371. <span class="token comment">/** @lends Fronteer.prototype */</span><span class="token punctuation">{</span>
  372. <span class="token function-variable function">_getLevel</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  373. <span class="token comment">// TODO</span>
  374. <span class="token punctuation">}</span>
  375. <span class="token punctuation">}</span>
  376. <span class="token punctuation">)</span><span class="token punctuation">;</span>
  377. </code></pre></div><h5 id="【强制】-类的属性或方法等成员信息使用-public-protected-private-中的任意一个-指明可访问性。"><a href="#【强制】-类的属性或方法等成员信息使用-public-protected-private-中的任意一个-指明可访问性。" class="header-anchor">#</a> <strong>【强制】</strong> 类的属性或方法等成员信息使用 <code>@public</code> / <code>@protected</code> / <code>@private</code> 中的任意一个,指明可访问性。</h5> <p>解释:</p> <p>生成的文档中将有可访问性的标记,避免用户直接使用非 <code>public</code> 的属性或方法。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">/**
  378. * 类描述
  379. *
  380. * @class
  381. * @extends Developer
  382. */</span>
  383. <span class="token keyword">var</span> <span class="token function-variable function">Fronteer</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  384. <span class="token function">Developer</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  385. <span class="token comment">/**
  386. * 属性描述
  387. *
  388. * @type {string}
  389. * @private
  390. */</span>
  391. <span class="token keyword">this</span><span class="token punctuation">.</span>_level <span class="token operator">=</span> <span class="token string">'T12'</span><span class="token punctuation">;</span>
  392. <span class="token comment">// constructor body</span>
  393. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  394. util<span class="token punctuation">.</span><span class="token function">inherits</span><span class="token punctuation">(</span>Fronteer<span class="token punctuation">,</span> Developer<span class="token punctuation">)</span><span class="token punctuation">;</span>
  395. <span class="token comment">/**
  396. * 方法描述
  397. *
  398. * @private
  399. * @return {string} 返回值描述
  400. */</span>
  401. <span class="token class-name">Fronteer</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">_getLevel</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  402. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  403. </code></pre></div><h4 id="_2-4-8-函数-方法注释"><a href="#_2-4-8-函数-方法注释" class="header-anchor">#</a> 2.4.8 函数/方法注释</h4> <h5 id="【强制】-函数-方法注释必须包含函数说明-有参数和返回值时必须使用注释标识。"><a href="#【强制】-函数-方法注释必须包含函数说明-有参数和返回值时必须使用注释标识。" class="header-anchor">#</a> <strong>【强制】</strong> 函数/方法注释必须包含函数说明,有参数和返回值时必须使用注释标识。</h5> <h5 id="【强制】-参数和返回值注释必须包含类型信息和说明。"><a href="#【强制】-参数和返回值注释必须包含类型信息和说明。" class="header-anchor">#</a> <strong>【强制】</strong> 参数和返回值注释必须包含类型信息和说明。</h5> <h5 id="【建议】-当函数是内部函数-外部不可访问时-可以使用-inner-标识。"><a href="#【建议】-当函数是内部函数-外部不可访问时-可以使用-inner-标识。" class="header-anchor">#</a> <strong>【建议】</strong> 当函数是内部函数,外部不可访问时,可以使用 <code>@inner</code> 标识。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">/**
  404. * 函数描述
  405. *
  406. * @param {string} p1 参数1的说明
  407. * @param {string} p2 参数2的说明,比较长
  408. * 那就换行了.
  409. * @param {number=} p3 参数3的说明(可选)
  410. * @return {Object} 返回值描述
  411. */</span>
  412. <span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token parameter">p1<span class="token punctuation">,</span> p2<span class="token punctuation">,</span> p3</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  413. <span class="token keyword">var</span> p3 <span class="token operator">=</span> p3 <span class="token operator">||</span> <span class="token number">10</span><span class="token punctuation">;</span>
  414. <span class="token keyword">return</span> <span class="token punctuation">{</span>
  415. <span class="token literal-property property">p1</span><span class="token operator">:</span> p1<span class="token punctuation">,</span>
  416. <span class="token literal-property property">p2</span><span class="token operator">:</span> p2<span class="token punctuation">,</span>
  417. <span class="token literal-property property">p3</span><span class="token operator">:</span> p3
  418. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  419. <span class="token punctuation">}</span>
  420. </code></pre></div><h5 id="【强制】-对-object-中各项的描述-必须使用-param-标识。"><a href="#【强制】-对-object-中各项的描述-必须使用-param-标识。" class="header-anchor">#</a> <strong>【强制】</strong> 对 Object 中各项的描述, 必须使用 <code>@param</code> 标识。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">/**
  421. * 函数描述
  422. *
  423. * @param {Object} option 参数描述
  424. * @param {string} option.url option项描述
  425. * @param {string=} option.method option项描述,可选参数
  426. */</span>
  427. <span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token parameter">option</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  428. <span class="token comment">// TODO</span>
  429. <span class="token punctuation">}</span>
  430. </code></pre></div><h5 id="【建议】-重写父类方法时-应当添加-override-标识。如果重写的形参个数、类型、顺序和返回值类型均未发生变化-可省略-param、-return-仅用-override-标识-否则仍应作完整注释。"><a href="#【建议】-重写父类方法时-应当添加-override-标识。如果重写的形参个数、类型、顺序和返回值类型均未发生变化-可省略-param、-return-仅用-override-标识-否则仍应作完整注释。" class="header-anchor">#</a> <strong>【建议】</strong> 重写父类方法时, 应当添加 <code>@override</code> 标识。如果重写的形参个数、类型、顺序和返回值类型均未发生变化,可省略 <code>@param</code>、<code>@return</code>,仅用 <code>@override</code> 标识,否则仍应作完整注释。</h5> <p>解释:</p> <p>简而言之,当子类重写的方法能直接套用父类的方法注释时可省略对参数与返回值的注释。</p> <h4 id="_2-4-9-事件注释"><a href="#_2-4-9-事件注释" class="header-anchor">#</a> 2.4.9 事件注释</h4> <h5 id="【强制】-必须使用-event-标识事件-事件参数的标识与方法描述的参数标识相同。"><a href="#【强制】-必须使用-event-标识事件-事件参数的标识与方法描述的参数标识相同。" class="header-anchor">#</a> <strong>【强制】</strong> 必须使用 <code>@event</code> 标识事件,事件参数的标识与方法描述的参数标识相同。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">/**
  431. * 值变更时触发
  432. *
  433. * @event
  434. * @param {Object} e e描述
  435. * @param {string} e.before before描述
  436. * @param {string} e.after after描述
  437. */</span>
  438. <span class="token function-variable function">onchange</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  439. <span class="token punctuation">}</span>
  440. </code></pre></div><h5 id="【强制】-在会广播事件的函数前使用-fires-标识广播的事件-在广播事件代码前使用-event-标识事件。"><a href="#【强制】-在会广播事件的函数前使用-fires-标识广播的事件-在广播事件代码前使用-event-标识事件。" class="header-anchor">#</a> <strong>【强制】</strong> 在会广播事件的函数前使用 <code>@fires</code> 标识广播的事件,在广播事件代码前使用 <code>@event</code> 标识事件。</h5> <h5 id="【建议】-对于事件对象的注释-使用-param-标识-生成文档时可读性更好。"><a href="#【建议】-对于事件对象的注释-使用-param-标识-生成文档时可读性更好。" class="header-anchor">#</a> <strong>【建议】</strong> 对于事件对象的注释,使用 <code>@param</code> 标识,生成文档时可读性更好。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">/**
  441. * 点击处理
  442. *
  443. * @fires Select#change
  444. * @private
  445. */</span>
  446. <span class="token class-name">Select</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">clickHandler</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  447. <span class="token comment">/**
  448. * 值变更时触发
  449. *
  450. * @event Select#change
  451. * @param {Object} e e描述
  452. * @param {string} e.before before描述
  453. * @param {string} e.after after描述
  454. */</span>
  455. <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">fire</span><span class="token punctuation">(</span>
  456. <span class="token string">'change'</span><span class="token punctuation">,</span>
  457. <span class="token punctuation">{</span>
  458. <span class="token literal-property property">before</span><span class="token operator">:</span> <span class="token string">'foo'</span><span class="token punctuation">,</span>
  459. <span class="token literal-property property">after</span><span class="token operator">:</span> <span class="token string">'bar'</span>
  460. <span class="token punctuation">}</span>
  461. <span class="token punctuation">)</span><span class="token punctuation">;</span>
  462. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  463. </code></pre></div><h4 id="_2-4-10-常量注释"><a href="#_2-4-10-常量注释" class="header-anchor">#</a> 2.4.10 常量注释</h4> <h5 id="【强制】-常量必须使用-const-标记-并包含说明和类型信息。"><a href="#【强制】-常量必须使用-const-标记-并包含说明和类型信息。" class="header-anchor">#</a> <strong>【强制】</strong> 常量必须使用 <code>@const</code> 标记,并包含说明和类型信息。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">/**
  464. * 常量说明
  465. *
  466. * @const
  467. * @type {string}
  468. */</span>
  469. <span class="token keyword">var</span> <span class="token constant">REQUEST_URL</span> <span class="token operator">=</span> <span class="token string">'myurl.do'</span><span class="token punctuation">;</span>
  470. </code></pre></div><h4 id="_2-4-11-复杂类型注释"><a href="#_2-4-11-复杂类型注释" class="header-anchor">#</a> 2.4.11 复杂类型注释</h4> <h5 id="【建议】-对于类型未定义的复杂结构的注释-可以使用-typedef-标识来定义。"><a href="#【建议】-对于类型未定义的复杂结构的注释-可以使用-typedef-标识来定义。" class="header-anchor">#</a> <strong>【建议】</strong> 对于类型未定义的复杂结构的注释,可以使用 <code>@typedef</code> 标识来定义。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// `namespaceA~` 可以换成其它 namepaths 前缀,目的是为了生成文档中能显示 `@typedef` 定义的类型和链接。</span>
  471. <span class="token comment">/**
  472. * 服务器
  473. *
  474. * @typedef {Object} namespaceA~Server
  475. * @property {string} host 主机
  476. * @property {number} port 端口
  477. */</span>
  478. <span class="token comment">/**
  479. * 服务器列表
  480. *
  481. * @type {Array.&lt;namespaceA~Server&gt;}
  482. */</span>
  483. <span class="token keyword">var</span> servers <span class="token operator">=</span> <span class="token punctuation">[</span>
  484. <span class="token punctuation">{</span>
  485. <span class="token literal-property property">host</span><span class="token operator">:</span> <span class="token string">'1.2.3.4'</span><span class="token punctuation">,</span>
  486. <span class="token literal-property property">port</span><span class="token operator">:</span> <span class="token number">8080</span>
  487. <span class="token punctuation">}</span><span class="token punctuation">,</span>
  488. <span class="token punctuation">{</span>
  489. <span class="token literal-property property">host</span><span class="token operator">:</span> <span class="token string">'1.2.3.5'</span><span class="token punctuation">,</span>
  490. <span class="token literal-property property">port</span><span class="token operator">:</span> <span class="token number">8081</span>
  491. <span class="token punctuation">}</span>
  492. <span class="token punctuation">]</span><span class="token punctuation">;</span>
  493. </code></pre></div><h4 id="_2-4-12-细节注释"><a href="#_2-4-12-细节注释" class="header-anchor">#</a> 2.4.12 细节注释</h4> <p>对于内部实现、不容易理解的逻辑说明、摘要信息等,我们可能需要编写细节注释。</p> <h4 id="【建议】-细节注释遵循单行注释的格式。说明必须换行时-每行是一个单行注释的起始。"><a href="#【建议】-细节注释遵循单行注释的格式。说明必须换行时-每行是一个单行注释的起始。" class="header-anchor">#</a> <strong>【建议】</strong> 细节注释遵循单行注释的格式。说明必须换行时,每行是一个单行注释的起始。</h4> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token parameter">p1<span class="token punctuation">,</span> p2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  494. <span class="token comment">// 这里对具体内部逻辑进行说明</span>
  495. <span class="token comment">// 说明太长需要换行</span>
  496. <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token operator">...</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  497. <span class="token operator">...</span><span class="token punctuation">.</span>
  498. <span class="token punctuation">}</span>
  499. <span class="token punctuation">}</span>
  500. </code></pre></div><h5 id="【强制】-有时我们会使用一些特殊标记进行说明。特殊标记必须使用单行注释的形式。下面列举了一些常用标记"><a href="#【强制】-有时我们会使用一些特殊标记进行说明。特殊标记必须使用单行注释的形式。下面列举了一些常用标记" class="header-anchor">#</a> <strong>【强制】</strong> 有时我们会使用一些特殊标记进行说明。特殊标记必须使用单行注释的形式。下面列举了一些常用标记:</h5> <p>解释:</p> <ol><li>TODO: 有功能待实现。此时需要对将要实现的功能进行简单说明。</li> <li>FIXME: 该处代码运行没问题,但可能由于时间赶或者其他原因,需要修正。此时需要对如何修正进行简单说明。</li> <li>HACK: 为修正某些问题而写的不太好或者使用了某些诡异手段的代码。此时需要对思路或诡异手段进行描述。</li> <li>XXX: 该处存在陷阱。此时需要对陷阱进行描述。</li></ol> <h2 id="_3-语言特性"><a href="#_3-语言特性" class="header-anchor">#</a> 3 语言特性</h2> <h3 id="_3-1-变量"><a href="#_3-1-变量" class="header-anchor">#</a> 3.1 变量</h3> <h5 id="【强制】-变量在使用前必须通过-var-定义。"><a href="#【强制】-变量在使用前必须通过-var-定义。" class="header-anchor">#</a> <strong>【强制】</strong> 变量在使用前必须通过 <code>var</code> 定义。</h5> <p>解释:</p> <p>不通过 var 定义变量将导致变量污染全局环境。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  501. <span class="token keyword">var</span> name <span class="token operator">=</span> <span class="token string">'MyName'</span><span class="token punctuation">;</span>
  502. <span class="token comment">// bad</span>
  503. name <span class="token operator">=</span> <span class="token string">'MyName'</span><span class="token punctuation">;</span>
  504. </code></pre></div><h5 id="【强制】-每个-var-只能声明一个变量。"><a href="#【强制】-每个-var-只能声明一个变量。" class="header-anchor">#</a> <strong>【强制】</strong> 每个 <code>var</code> 只能声明一个变量。</h5> <p>解释:</p> <p>一个 var 声明多个变量,容易导致较长的行长度,并且在修改时容易造成逗号和分号的混淆。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  505. <span class="token keyword">var</span> hangModules <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  506. <span class="token keyword">var</span> missModules <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  507. <span class="token keyword">var</span> visited <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  508. <span class="token comment">// bad</span>
  509. <span class="token keyword">var</span> hangModules <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
  510. missModules <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
  511. visited <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  512. </code></pre></div><h5 id="【强制】-变量必须-即用即声明-不得在函数或其它形式的代码块起始位置统一声明所有变量。"><a href="#【强制】-变量必须-即用即声明-不得在函数或其它形式的代码块起始位置统一声明所有变量。" class="header-anchor">#</a> <strong>【强制】</strong> 变量必须 <code>即用即声明</code>,不得在函数或其它形式的代码块起始位置统一声明所有变量。</h5> <p>解释:</p> <p>变量声明与使用的距离越远,出现的跨度越大,代码的阅读与维护成本越高。虽然JavaScript的变量是函数作用域,还是应该根据编程中的意图,缩小变量出现的距离空间。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  513. <span class="token keyword">function</span> <span class="token function">kv2List</span><span class="token punctuation">(</span><span class="token parameter">source</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  514. <span class="token keyword">var</span> list <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  515. <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> key <span class="token keyword">in</span> source<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  516. <span class="token keyword">if</span> <span class="token punctuation">(</span>source<span class="token punctuation">.</span><span class="token function">hasOwnProperty</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  517. <span class="token keyword">var</span> item <span class="token operator">=</span> <span class="token punctuation">{</span>
  518. <span class="token literal-property property">k</span><span class="token operator">:</span> key<span class="token punctuation">,</span>
  519. <span class="token literal-property property">v</span><span class="token operator">:</span> source<span class="token punctuation">[</span>key<span class="token punctuation">]</span>
  520. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  521. list<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span>
  522. <span class="token punctuation">}</span>
  523. <span class="token punctuation">}</span>
  524. <span class="token keyword">return</span> list<span class="token punctuation">;</span>
  525. <span class="token punctuation">}</span>
  526. <span class="token comment">// bad</span>
  527. <span class="token keyword">function</span> <span class="token function">kv2List</span><span class="token punctuation">(</span><span class="token parameter">source</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  528. <span class="token keyword">var</span> list <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  529. <span class="token keyword">var</span> key<span class="token punctuation">;</span>
  530. <span class="token keyword">var</span> item<span class="token punctuation">;</span>
  531. <span class="token keyword">for</span> <span class="token punctuation">(</span>key <span class="token keyword">in</span> source<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  532. <span class="token keyword">if</span> <span class="token punctuation">(</span>source<span class="token punctuation">.</span><span class="token function">hasOwnProperty</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  533. item <span class="token operator">=</span> <span class="token punctuation">{</span>
  534. <span class="token literal-property property">k</span><span class="token operator">:</span> key<span class="token punctuation">,</span>
  535. <span class="token literal-property property">v</span><span class="token operator">:</span> source<span class="token punctuation">[</span>key<span class="token punctuation">]</span>
  536. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  537. list<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">;</span>
  538. <span class="token punctuation">}</span>
  539. <span class="token punctuation">}</span>
  540. <span class="token keyword">return</span> list<span class="token punctuation">;</span>
  541. <span class="token punctuation">}</span>
  542. </code></pre></div><h3 id="_3-2-条件"><a href="#_3-2-条件" class="header-anchor">#</a> 3.2 条件</h3> <h5 id="【强制】-在-equality-expression-中使用类型严格的-。仅当判断-null-或-undefined-时-允许使用-null。"><a href="#【强制】-在-equality-expression-中使用类型严格的-。仅当判断-null-或-undefined-时-允许使用-null。" class="header-anchor">#</a> <strong>【强制】</strong> 在 Equality Expression 中使用类型严格的 <code>===</code>。仅当判断 null 或 undefined 时,允许使用 <code>== null</code>。</h5> <p>解释:</p> <p>使用 === 可以避免等于判断中隐式的类型转换。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  543. <span class="token keyword">if</span> <span class="token punctuation">(</span>age <span class="token operator">===</span> <span class="token number">30</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  544. <span class="token comment">// ......</span>
  545. <span class="token punctuation">}</span>
  546. <span class="token comment">// bad</span>
  547. <span class="token keyword">if</span> <span class="token punctuation">(</span>age <span class="token operator">==</span> <span class="token number">30</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  548. <span class="token comment">// ......</span>
  549. <span class="token punctuation">}</span>
  550. </code></pre></div><h5 id="【建议】-尽可能使用简洁的表达式。"><a href="#【建议】-尽可能使用简洁的表达式。" class="header-anchor">#</a> <strong>【建议】</strong> 尽可能使用简洁的表达式。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// 字符串为空</span>
  551. <span class="token comment">// good</span>
  552. <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>name<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  553. <span class="token comment">// ......</span>
  554. <span class="token punctuation">}</span>
  555. <span class="token comment">// bad</span>
  556. <span class="token keyword">if</span> <span class="token punctuation">(</span>name <span class="token operator">===</span> <span class="token string">''</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  557. <span class="token comment">// ......</span>
  558. <span class="token punctuation">}</span>
  559. </code></pre></div><div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// 字符串非空</span>
  560. <span class="token comment">// good</span>
  561. <span class="token keyword">if</span> <span class="token punctuation">(</span>name<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  562. <span class="token comment">// ......</span>
  563. <span class="token punctuation">}</span>
  564. <span class="token comment">// bad</span>
  565. <span class="token keyword">if</span> <span class="token punctuation">(</span>name <span class="token operator">!==</span> <span class="token string">''</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  566. <span class="token comment">// ......</span>
  567. <span class="token punctuation">}</span>
  568. </code></pre></div><div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// 数组非空</span>
  569. <span class="token comment">// good</span>
  570. <span class="token keyword">if</span> <span class="token punctuation">(</span>collection<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  571. <span class="token comment">// ......</span>
  572. <span class="token punctuation">}</span>
  573. <span class="token comment">// bad</span>
  574. <span class="token keyword">if</span> <span class="token punctuation">(</span>collection<span class="token punctuation">.</span>length <span class="token operator">&gt;</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  575. <span class="token comment">// ......</span>
  576. <span class="token punctuation">}</span>
  577. </code></pre></div><div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// 布尔不成立</span>
  578. <span class="token comment">// good</span>
  579. <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>notTrue<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  580. <span class="token comment">// ......</span>
  581. <span class="token punctuation">}</span>
  582. <span class="token comment">// bad</span>
  583. <span class="token keyword">if</span> <span class="token punctuation">(</span>notTrue <span class="token operator">===</span> <span class="token boolean">false</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  584. <span class="token comment">// ......</span>
  585. <span class="token punctuation">}</span>
  586. </code></pre></div><div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// null 或 undefined</span>
  587. <span class="token comment">// good</span>
  588. <span class="token keyword">if</span> <span class="token punctuation">(</span>noValue <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  589. <span class="token comment">// ......</span>
  590. <span class="token punctuation">}</span>
  591. <span class="token comment">// bad</span>
  592. <span class="token keyword">if</span> <span class="token punctuation">(</span>noValue <span class="token operator">===</span> <span class="token keyword">null</span> <span class="token operator">||</span> <span class="token keyword">typeof</span> noValue <span class="token operator">===</span> <span class="token string">'undefined'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  593. <span class="token comment">// ......</span>
  594. <span class="token punctuation">}</span>
  595. </code></pre></div><h5 id="【建议】-按执行频率排列分支的顺序。"><a href="#【建议】-按执行频率排列分支的顺序。" class="header-anchor">#</a> <strong>【建议】</strong> 按执行频率排列分支的顺序。</h5> <p>解释:</p> <p>按执行频率排列分支的顺序好处是:</p> <ol><li>阅读的人容易找到最常见的情况,增加可读性。</li> <li>提高执行效率。</li></ol> <h5 id="【建议】-对于相同变量或表达式的多值条件-用-switch-代替-if。"><a href="#【建议】-对于相同变量或表达式的多值条件-用-switch-代替-if。" class="header-anchor">#</a> <strong>【建议】</strong> 对于相同变量或表达式的多值条件,用 <code>switch</code> 代替 <code>if</code>。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  596. <span class="token keyword">switch</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> variable<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  597. <span class="token keyword">case</span> <span class="token string">'object'</span><span class="token operator">:</span>
  598. <span class="token comment">// ......</span>
  599. <span class="token keyword">break</span><span class="token punctuation">;</span>
  600. <span class="token keyword">case</span> <span class="token string">'number'</span><span class="token operator">:</span>
  601. <span class="token keyword">case</span> <span class="token string">'boolean'</span><span class="token operator">:</span>
  602. <span class="token keyword">case</span> <span class="token string">'string'</span><span class="token operator">:</span>
  603. <span class="token comment">// ......</span>
  604. <span class="token keyword">break</span><span class="token punctuation">;</span>
  605. <span class="token punctuation">}</span>
  606. <span class="token comment">// bad</span>
  607. <span class="token keyword">var</span> type <span class="token operator">=</span> <span class="token keyword">typeof</span> variable<span class="token punctuation">;</span>
  608. <span class="token keyword">if</span> <span class="token punctuation">(</span>type <span class="token operator">===</span> <span class="token string">'object'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  609. <span class="token comment">// ......</span>
  610. <span class="token punctuation">}</span>
  611. <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>type <span class="token operator">===</span> <span class="token string">'number'</span> <span class="token operator">||</span> type <span class="token operator">===</span> <span class="token string">'boolean'</span> <span class="token operator">||</span> type <span class="token operator">===</span> <span class="token string">'string'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  612. <span class="token comment">// ......</span>
  613. <span class="token punctuation">}</span>
  614. </code></pre></div><h5 id="【建议】-如果函数或全局中的-else-块后没有任何语句-可以删除-else。"><a href="#【建议】-如果函数或全局中的-else-块后没有任何语句-可以删除-else。" class="header-anchor">#</a> <strong>【建议】</strong> 如果函数或全局中的 <code>else</code> 块后没有任何语句,可以删除 <code>else</code>。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  615. <span class="token keyword">function</span> <span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  616. <span class="token keyword">if</span> <span class="token punctuation">(</span>name<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  617. <span class="token keyword">return</span> name<span class="token punctuation">;</span>
  618. <span class="token punctuation">}</span>
  619. <span class="token keyword">return</span> <span class="token string">'unnamed'</span><span class="token punctuation">;</span>
  620. <span class="token punctuation">}</span>
  621. <span class="token comment">// bad</span>
  622. <span class="token keyword">function</span> <span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  623. <span class="token keyword">if</span> <span class="token punctuation">(</span>name<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  624. <span class="token keyword">return</span> name<span class="token punctuation">;</span>
  625. <span class="token punctuation">}</span>
  626. <span class="token keyword">else</span> <span class="token punctuation">{</span>
  627. <span class="token keyword">return</span> <span class="token string">'unnamed'</span><span class="token punctuation">;</span>
  628. <span class="token punctuation">}</span>
  629. <span class="token punctuation">}</span>
  630. </code></pre></div><h3 id="_3-3-循环"><a href="#_3-3-循环" class="header-anchor">#</a> 3.3 循环</h3> <h5 id="【建议】-不要在循环体中包含函数表达式-事先将函数提取到循环体外。"><a href="#【建议】-不要在循环体中包含函数表达式-事先将函数提取到循环体外。" class="header-anchor">#</a> <strong>【建议】</strong> 不要在循环体中包含函数表达式,事先将函数提取到循环体外。</h5> <p>解释:</p> <p>循环体中的函数表达式,运行过程中会生成循环次数个函数对象。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  631. <span class="token keyword">function</span> <span class="token function">clicker</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  632. <span class="token comment">// ......</span>
  633. <span class="token punctuation">}</span>
  634. <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> len <span class="token operator">=</span> elements<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i <span class="token operator">&lt;</span> len<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  635. <span class="token keyword">var</span> element <span class="token operator">=</span> elements<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>
  636. <span class="token function">addListener</span><span class="token punctuation">(</span>element<span class="token punctuation">,</span> <span class="token string">'click'</span><span class="token punctuation">,</span> clicker<span class="token punctuation">)</span><span class="token punctuation">;</span>
  637. <span class="token punctuation">}</span>
  638. <span class="token comment">// bad</span>
  639. <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> len <span class="token operator">=</span> elements<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i <span class="token operator">&lt;</span> len<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  640. <span class="token keyword">var</span> element <span class="token operator">=</span> elements<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>
  641. <span class="token function">addListener</span><span class="token punctuation">(</span>element<span class="token punctuation">,</span> <span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  642. <span class="token punctuation">}</span>
  643. </code></pre></div><h5 id="【建议】-对循环内多次使用的不变值-在循环外用变量缓存。"><a href="#【建议】-对循环内多次使用的不变值-在循环外用变量缓存。" class="header-anchor">#</a> <strong>【建议】</strong> 对循环内多次使用的不变值,在循环外用变量缓存。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  644. <span class="token keyword">var</span> width <span class="token operator">=</span> wrap<span class="token punctuation">.</span>offsetWidth <span class="token operator">+</span> <span class="token string">'px'</span><span class="token punctuation">;</span>
  645. <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> len <span class="token operator">=</span> elements<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i <span class="token operator">&lt;</span> len<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  646. <span class="token keyword">var</span> element <span class="token operator">=</span> elements<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>
  647. element<span class="token punctuation">.</span>style<span class="token punctuation">.</span>width <span class="token operator">=</span> width<span class="token punctuation">;</span>
  648. <span class="token comment">// ......</span>
  649. <span class="token punctuation">}</span>
  650. <span class="token comment">// bad</span>
  651. <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> len <span class="token operator">=</span> elements<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i <span class="token operator">&lt;</span> len<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  652. <span class="token keyword">var</span> element <span class="token operator">=</span> elements<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>
  653. element<span class="token punctuation">.</span>style<span class="token punctuation">.</span>width <span class="token operator">=</span> wrap<span class="token punctuation">.</span>offsetWidth <span class="token operator">+</span> <span class="token string">'px'</span><span class="token punctuation">;</span>
  654. <span class="token comment">// ......</span>
  655. <span class="token punctuation">}</span>
  656. </code></pre></div><h5 id="【建议】-对有序集合进行遍历时-缓存-length。"><a href="#【建议】-对有序集合进行遍历时-缓存-length。" class="header-anchor">#</a> <strong>【建议】</strong> 对有序集合进行遍历时,缓存 <code>length</code>。</h5> <p>解释:</p> <p>虽然现代浏览器都对数组长度进行了缓存,但对于一些宿主对象和老旧浏览器的数组对象,在每次 length 访问时会动态计算元素个数,此时缓存 length 能有效提高程序性能。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> len <span class="token operator">=</span> elements<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i <span class="token operator">&lt;</span> len<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  657. <span class="token keyword">var</span> element <span class="token operator">=</span> elements<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>
  658. <span class="token comment">// ......</span>
  659. <span class="token punctuation">}</span>
  660. </code></pre></div><h5 id="【建议】-对有序集合进行顺序无关的遍历时-使用逆序遍历。"><a href="#【建议】-对有序集合进行顺序无关的遍历时-使用逆序遍历。" class="header-anchor">#</a> <strong>【建议】</strong> 对有序集合进行顺序无关的遍历时,使用逆序遍历。</h5> <p>解释:</p> <p>逆序遍历可以节省变量,代码比较优化。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">var</span> len <span class="token operator">=</span> elements<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
  661. <span class="token keyword">while</span> <span class="token punctuation">(</span>len<span class="token operator">--</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  662. <span class="token keyword">var</span> element <span class="token operator">=</span> elements<span class="token punctuation">[</span>len<span class="token punctuation">]</span><span class="token punctuation">;</span>
  663. <span class="token comment">// ......</span>
  664. <span class="token punctuation">}</span>
  665. </code></pre></div><h3 id="_3-4-类型"><a href="#_3-4-类型" class="header-anchor">#</a> 3.4 类型</h3> <h4 id="_3-4-1-类型检测"><a href="#_3-4-1-类型检测" class="header-anchor">#</a> 3.4.1 类型检测</h4> <h5 id="【建议】-类型检测优先使用-typeof。对象类型检测使用-instanceof。null-或-undefined-的检测使用-null。"><a href="#【建议】-类型检测优先使用-typeof。对象类型检测使用-instanceof。null-或-undefined-的检测使用-null。" class="header-anchor">#</a> <strong>【建议】</strong> 类型检测优先使用 <code>typeof</code>。对象类型检测使用 <code>instanceof</code>。<code>null</code> 或 <code>undefined</code> 的检测使用 <code>== null</code>。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// string</span>
  666. <span class="token keyword">typeof</span> variable <span class="token operator">===</span> <span class="token string">'string'</span>
  667. <span class="token comment">// number</span>
  668. <span class="token keyword">typeof</span> variable <span class="token operator">===</span> <span class="token string">'number'</span>
  669. <span class="token comment">// boolean</span>
  670. <span class="token keyword">typeof</span> variable <span class="token operator">===</span> <span class="token string">'boolean'</span>
  671. <span class="token comment">// Function</span>
  672. <span class="token keyword">typeof</span> variable <span class="token operator">===</span> <span class="token string">'function'</span>
  673. <span class="token comment">// Object</span>
  674. <span class="token keyword">typeof</span> variable <span class="token operator">===</span> <span class="token string">'object'</span>
  675. <span class="token comment">// RegExp</span>
  676. variable <span class="token keyword">instanceof</span> <span class="token class-name">RegExp</span>
  677. <span class="token comment">// Array</span>
  678. variable <span class="token keyword">instanceof</span> <span class="token class-name">Array</span>
  679. <span class="token comment">// null</span>
  680. variable <span class="token operator">===</span> <span class="token keyword">null</span>
  681. <span class="token comment">// null or undefined</span>
  682. variable <span class="token operator">==</span> <span class="token keyword">null</span>
  683. <span class="token comment">// undefined</span>
  684. <span class="token keyword">typeof</span> variable <span class="token operator">===</span> <span class="token string">'undefined'</span>
  685. </code></pre></div><h4 id="_3-4-2-类型转换"><a href="#_3-4-2-类型转换" class="header-anchor">#</a> 3.4.2 类型转换</h4> <h5 id="【建议】-转换成-string-时-使用-。"><a href="#【建议】-转换成-string-时-使用-。" class="header-anchor">#</a> <strong>【建议】</strong> 转换成 <code>string</code> 时,使用 <code>+ ''</code>。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  686. num <span class="token operator">+</span> <span class="token string">''</span><span class="token punctuation">;</span>
  687. <span class="token comment">// bad</span>
  688. <span class="token keyword">new</span> <span class="token class-name">String</span><span class="token punctuation">(</span>num<span class="token punctuation">)</span><span class="token punctuation">;</span>
  689. num<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  690. <span class="token function">String</span><span class="token punctuation">(</span>num<span class="token punctuation">)</span><span class="token punctuation">;</span>
  691. </code></pre></div><h5 id="【建议】-转换成-number-时-通常使用-。"><a href="#【建议】-转换成-number-时-通常使用-。" class="header-anchor">#</a> <strong>【建议】</strong> 转换成 <code>number</code> 时,通常使用 <code>+</code>。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  692. <span class="token operator">+</span>str<span class="token punctuation">;</span>
  693. <span class="token comment">// bad</span>
  694. <span class="token function">Number</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span>
  695. </code></pre></div><h5 id="【建议】-string-转换成-number-要转换的字符串结尾包含非数字并期望忽略时-使用-parseint。"><a href="#【建议】-string-转换成-number-要转换的字符串结尾包含非数字并期望忽略时-使用-parseint。" class="header-anchor">#</a> <strong>【建议】</strong> <code>string</code> 转换成 <code>number</code>,要转换的字符串结尾包含非数字并期望忽略时,使用 <code>parseInt</code>。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">var</span> width <span class="token operator">=</span> <span class="token string">'200px'</span><span class="token punctuation">;</span>
  696. <span class="token function">parseInt</span><span class="token punctuation">(</span>width<span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  697. </code></pre></div><h5 id="【强制】-使用-parseint-时-必须指定进制。"><a href="#【强制】-使用-parseint-时-必须指定进制。" class="header-anchor">#</a> <strong>【强制】</strong> 使用 <code>parseInt</code> 时,必须指定进制。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  698. <span class="token function">parseInt</span><span class="token punctuation">(</span>str<span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  699. <span class="token comment">// bad</span>
  700. <span class="token function">parseInt</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span><span class="token punctuation">;</span>
  701. </code></pre></div><h5 id="【建议】-转换成-boolean-时-使用-。"><a href="#【建议】-转换成-boolean-时-使用-。" class="header-anchor">#</a> <strong>【建议】</strong> 转换成 <code>boolean</code> 时,使用 <code>!!</code>。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">var</span> num <span class="token operator">=</span> <span class="token number">3.14</span><span class="token punctuation">;</span>
  702. <span class="token operator">!</span><span class="token operator">!</span>num<span class="token punctuation">;</span>
  703. </code></pre></div><h5 id="【建议】-number-去除小数点-使用-math-floor-math-round-math-ceil-不使用-parseint。"><a href="#【建议】-number-去除小数点-使用-math-floor-math-round-math-ceil-不使用-parseint。" class="header-anchor">#</a> <strong>【建议】</strong> <code>number</code> 去除小数点,使用 <code>Math.floor / Math.round / Math.ceil</code>,不使用 <code>parseInt</code>。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  704. <span class="token keyword">var</span> num <span class="token operator">=</span> <span class="token number">3.14</span><span class="token punctuation">;</span>
  705. Math<span class="token punctuation">.</span><span class="token function">ceil</span><span class="token punctuation">(</span>num<span class="token punctuation">)</span><span class="token punctuation">;</span>
  706. <span class="token comment">// bad</span>
  707. <span class="token keyword">var</span> num <span class="token operator">=</span> <span class="token number">3.14</span><span class="token punctuation">;</span>
  708. <span class="token function">parseInt</span><span class="token punctuation">(</span>num<span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  709. </code></pre></div><h3 id="_3-5-字符串"><a href="#_3-5-字符串" class="header-anchor">#</a> 3.5 字符串</h3> <h5 id="【强制】-字符串开头和结束使用单引号-。"><a href="#【强制】-字符串开头和结束使用单引号-。" class="header-anchor">#</a> <strong>【强制】</strong> 字符串开头和结束使用单引号 <code>'</code>。</h5> <p>解释:</p> <ol><li>输入单引号不需要按住 shift,方便输入。</li> <li>实际使用中,字符串经常用来拼接 HTML。为方便 HTML 中包含双引号而不需要转义写法。</li></ol> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">var</span> str <span class="token operator">=</span> <span class="token string">'我是一个字符串'</span><span class="token punctuation">;</span>
  710. <span class="token keyword">var</span> html <span class="token operator">=</span> <span class="token string">'&lt;div class=&quot;cls&quot;&gt;拼接HTML可以省去双引号转义&lt;/div&gt;'</span><span class="token punctuation">;</span>
  711. </code></pre></div><h5 id="【建议】-使用-数组-或-拼接字符串。"><a href="#【建议】-使用-数组-或-拼接字符串。" class="header-anchor">#</a> <strong>【建议】</strong> 使用 <code>数组</code> 或 <code>+</code> 拼接字符串。</h5> <p>解释:</p> <ol><li>使用 + 拼接字符串,如果拼接的全部是 StringLiteral,压缩工具可以对其进行自动合并的优化。所以,静态字符串建议使用 + 拼接。</li> <li>在现代浏览器下,使用 + 拼接字符串,性能较数组的方式要高。</li> <li>如需要兼顾老旧浏览器,应尽量使用数组拼接字符串。</li></ol> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// 使用数组拼接字符串</span>
  712. <span class="token keyword">var</span> str <span class="token operator">=</span> <span class="token punctuation">[</span>
  713. <span class="token comment">// 推荐换行开始并缩进开始第一个字符串, 对齐代码, 方便阅读.</span>
  714. <span class="token string">'&lt;ul&gt;'</span><span class="token punctuation">,</span>
  715. <span class="token string">'&lt;li&gt;第一项&lt;/li&gt;'</span><span class="token punctuation">,</span>
  716. <span class="token string">'&lt;li&gt;第二项&lt;/li&gt;'</span><span class="token punctuation">,</span>
  717. <span class="token string">'&lt;/ul&gt;'</span>
  718. <span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">''</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  719. <span class="token comment">// 使用 + 拼接字符串</span>
  720. <span class="token keyword">var</span> str2 <span class="token operator">=</span> <span class="token string">''</span> <span class="token comment">// 建议第一个为空字符串, 第二个换行开始并缩进开始, 对齐代码, 方便阅读</span>
  721. <span class="token operator">+</span> <span class="token string">'&lt;ul&gt;'</span><span class="token punctuation">,</span>
  722. <span class="token operator">+</span> <span class="token string">'&lt;li&gt;第一项&lt;/li&gt;'</span><span class="token punctuation">,</span>
  723. <span class="token operator">+</span> <span class="token string">'&lt;li&gt;第二项&lt;/li&gt;'</span><span class="token punctuation">,</span>
  724. <span class="token operator">+</span> <span class="token string">'&lt;/ul&gt;'</span><span class="token punctuation">;</span>
  725. </code></pre></div><h5 id="【建议】-复杂的数据到视图字符串的转换过程-选用一种模板引擎。"><a href="#【建议】-复杂的数据到视图字符串的转换过程-选用一种模板引擎。" class="header-anchor">#</a> <strong>【建议】</strong> 复杂的数据到视图字符串的转换过程,选用一种模板引擎。</h5> <p>解释:</p> <p>使用模板引擎有如下好处:</p> <ol><li>在开发过程中专注于数据,将视图生成的过程由另外一个层级维护,使程序逻辑结构更清晰。</li> <li>优秀的模板引擎,通过模板编译技术和高质量的编译产物,能获得比手工拼接字符串更高的性能。</li></ol> <ul><li>artTemplate: 体积较小,在所有环境下性能高,语法灵活。</li> <li>dot.js: 体积小,在现代浏览器下性能高,语法灵活。</li> <li>etpl: 体积较小,在所有环境下性能高,模板复用性高,语法灵活。</li> <li>handlebars: 体积大,在所有环境下性能高,扩展性高。</li> <li>hogon: 体积小,在现代浏览器下性能高。</li> <li>nunjucks: 体积较大,性能一般,模板复用性高。</li></ul> <h3 id="_3-6-对象"><a href="#_3-6-对象" class="header-anchor">#</a> 3.6 对象</h3> <h5 id="【强制】-使用对象字面量-创建新-object。"><a href="#【强制】-使用对象字面量-创建新-object。" class="header-anchor">#</a> <strong>【强制】</strong> 使用对象字面量 <code>{}</code> 创建新 <code>Object</code>。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  726. <span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  727. <span class="token comment">// bad</span>
  728. <span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Object</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  729. </code></pre></div><h5 id="【强制】-对象创建时-如果一个对象的所有-属性-均可以不添加引号-则所有-属性-不得添加引号。"><a href="#【强制】-对象创建时-如果一个对象的所有-属性-均可以不添加引号-则所有-属性-不得添加引号。" class="header-anchor">#</a> <strong>【强制】</strong> 对象创建时,如果一个对象的所有 <code>属性</code> 均可以不添加引号,则所有 <code>属性</code> 不得添加引号。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">var</span> info <span class="token operator">=</span> <span class="token punctuation">{</span>
  730. <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'someone'</span><span class="token punctuation">,</span>
  731. <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">28</span>
  732. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  733. </code></pre></div><h5 id="【强制】-对象创建时-如果任何一个-属性-需要添加引号-则所有-属性-必须添加-。"><a href="#【强制】-对象创建时-如果任何一个-属性-需要添加引号-则所有-属性-必须添加-。" class="header-anchor">#</a> <strong>【强制】</strong> 对象创建时,如果任何一个 <code>属性</code> 需要添加引号,则所有 <code>属性</code> 必须添加 <code>'</code>。</h5> <p>解释:</p> <p>如果属性不符合 Identifier 和 NumberLiteral 的形式,就需要以 StringLiteral 的形式提供。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  734. <span class="token keyword">var</span> info <span class="token operator">=</span> <span class="token punctuation">{</span>
  735. <span class="token string-property property">'name'</span><span class="token operator">:</span> <span class="token string">'someone'</span><span class="token punctuation">,</span>
  736. <span class="token string-property property">'age'</span><span class="token operator">:</span> <span class="token number">28</span><span class="token punctuation">,</span>
  737. <span class="token string-property property">'more-info'</span><span class="token operator">:</span> <span class="token string">'...'</span>
  738. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  739. <span class="token comment">// bad</span>
  740. <span class="token keyword">var</span> info <span class="token operator">=</span> <span class="token punctuation">{</span>
  741. <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'someone'</span><span class="token punctuation">,</span>
  742. <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">28</span><span class="token punctuation">,</span>
  743. <span class="token string-property property">'more-info'</span><span class="token operator">:</span> <span class="token string">'...'</span>
  744. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  745. </code></pre></div><h5 id="【强制】-不允许修改和扩展任何原生对象和宿主对象的原型。"><a href="#【强制】-不允许修改和扩展任何原生对象和宿主对象的原型。" class="header-anchor">#</a> <strong>【强制】</strong> 不允许修改和扩展任何原生对象和宿主对象的原型。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// 以下行为绝对禁止</span>
  746. <span class="token class-name">String</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">trim</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  747. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  748. </code></pre></div><h5 id="【建议】-属性访问时-尽量使用-。"><a href="#【建议】-属性访问时-尽量使用-。" class="header-anchor">#</a> <strong>【建议】</strong> 属性访问时,尽量使用 <code>.</code>。</h5> <p>解释:</p> <p>属性名符合 Identifier 的要求,就可以通过 <code>.</code> 来访问,否则就只能通过 <code>[expr]</code> 方式访问。</p> <p>通常在 JavaScript 中声明的对象,属性命名是使用 Camel 命名法,用 <code>.</code> 来访问更清晰简洁。部分特殊的属性(比如来自后端的JSON),可能采用不寻常的命名方式,可以通过 <code>[expr]</code> 方式访问。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code>info<span class="token punctuation">.</span>age<span class="token punctuation">;</span>
  749. info<span class="token punctuation">[</span><span class="token string">'more-info'</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  750. </code></pre></div><h5 id="【建议】-for-in-遍历对象时-使用-hasownproperty-过滤掉原型中的属性。"><a href="#【建议】-for-in-遍历对象时-使用-hasownproperty-过滤掉原型中的属性。" class="header-anchor">#</a> <strong>【建议】</strong> <code>for in</code> 遍历对象时, 使用 <code>hasOwnProperty</code> 过滤掉原型中的属性。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">var</span> newInfo <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  751. <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> key <span class="token keyword">in</span> info<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  752. <span class="token keyword">if</span> <span class="token punctuation">(</span>info<span class="token punctuation">.</span><span class="token function">hasOwnProperty</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  753. newInfo<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> info<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span>
  754. <span class="token punctuation">}</span>
  755. <span class="token punctuation">}</span>
  756. </code></pre></div><h3 id="_3-7-数组"><a href="#_3-7-数组" class="header-anchor">#</a> 3.7 数组</h3> <h5 id="【强制】-使用数组字面量-创建新数组-除非想要创建的是指定长度的数组。"><a href="#【强制】-使用数组字面量-创建新数组-除非想要创建的是指定长度的数组。" class="header-anchor">#</a> <strong>【强制】</strong> 使用数组字面量 <code>[]</code> 创建新数组,除非想要创建的是指定长度的数组。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// good</span>
  757. <span class="token keyword">var</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  758. <span class="token comment">// bad</span>
  759. <span class="token keyword">var</span> arr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Array</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  760. </code></pre></div><h5 id="【强制】-遍历数组不使用-for-in。"><a href="#【强制】-遍历数组不使用-for-in。" class="header-anchor">#</a> <strong>【强制】</strong> 遍历数组不使用 <code>for in</code>。</h5> <p>解释:</p> <p>数组对象可能存在数字以外的属性, 这种情况下 for in 不会得到正确结果.</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">var</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'a'</span><span class="token punctuation">,</span> <span class="token string">'b'</span><span class="token punctuation">,</span> <span class="token string">'c'</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  761. arr<span class="token punctuation">.</span>other <span class="token operator">=</span> <span class="token string">'other things'</span><span class="token punctuation">;</span> <span class="token comment">// 这里仅作演示, 实际中应使用Object类型</span>
  762. <span class="token comment">// 正确的遍历方式</span>
  763. <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> len <span class="token operator">=</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i <span class="token operator">&lt;</span> len<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  764. console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
  765. <span class="token punctuation">}</span>
  766. <span class="token comment">// 错误的遍历方式</span>
  767. <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token keyword">in</span> arr<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  768. console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
  769. <span class="token punctuation">}</span>
  770. </code></pre></div><h5 id="【建议】-不因为性能的原因自己实现数组排序功能-尽量使用数组的-sort-方法。"><a href="#【建议】-不因为性能的原因自己实现数组排序功能-尽量使用数组的-sort-方法。" class="header-anchor">#</a> <strong>【建议】</strong> 不因为性能的原因自己实现数组排序功能,尽量使用数组的 <code>sort</code> 方法。</h5> <p>解释:</p> <p>自己实现的常规排序算法,在性能上并不优于数组默认的 sort 方法。以下两种场景可以自己实现排序:</p> <ol><li>需要稳定的排序算法,达到严格一致的排序结果。</li> <li>数据特点鲜明,适合使用桶排。</li></ol> <h5 id="【建议】-清空数组使用-length-0。"><a href="#【建议】-清空数组使用-length-0。" class="header-anchor">#</a> <strong>【建议】</strong> 清空数组使用 <code>.length = 0</code>。</h5> <h3 id="_3-8-函数"><a href="#_3-8-函数" class="header-anchor">#</a> 3.8 函数</h3> <h4 id="_3-8-1-函数长度"><a href="#_3-8-1-函数长度" class="header-anchor">#</a> 3.8.1 函数长度</h4> <h5 id="【建议】-一个函数的长度控制在-50-行以内。"><a href="#【建议】-一个函数的长度控制在-50-行以内。" class="header-anchor">#</a> <strong>【建议】</strong> 一个函数的长度控制在 <code>50</code> 行以内。</h5> <p>解释:</p> <p>将过多的逻辑单元混在一个大函数中,易导致难以维护。一个清晰易懂的函数应该完成单一的逻辑单元。复杂的操作应进一步抽取,通过函数的调用来体现流程。</p> <p>特定算法等不可分割的逻辑允许例外。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">function</span> <span class="token function">syncViewStateOnUserAction</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  771. <span class="token keyword">if</span> <span class="token punctuation">(</span>x<span class="token punctuation">.</span>checked<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  772. y<span class="token punctuation">.</span>checked <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
  773. z<span class="token punctuation">.</span>value <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">;</span>
  774. <span class="token punctuation">}</span>
  775. <span class="token keyword">else</span> <span class="token punctuation">{</span>
  776. y<span class="token punctuation">.</span>checked <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
  777. <span class="token punctuation">}</span>
  778. <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>a<span class="token punctuation">.</span>value<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  779. warning<span class="token punctuation">.</span>innerText <span class="token operator">=</span> <span class="token string">'Please enter it'</span><span class="token punctuation">;</span>
  780. submitButton<span class="token punctuation">.</span>disabled <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
  781. <span class="token punctuation">}</span>
  782. <span class="token keyword">else</span> <span class="token punctuation">{</span>
  783. warning<span class="token punctuation">.</span>innerText <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">;</span>
  784. submitButton<span class="token punctuation">.</span>disabled <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
  785. <span class="token punctuation">}</span>
  786. <span class="token punctuation">}</span>
  787. <span class="token comment">// 直接阅读该函数会难以明确其主线逻辑,因此下方是一种更合理的表达方式:</span>
  788. <span class="token keyword">function</span> <span class="token function">syncViewStateOnUserAction</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  789. <span class="token function">syncXStateToView</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  790. <span class="token function">checkAAvailability</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  791. <span class="token punctuation">}</span>
  792. <span class="token keyword">function</span> <span class="token function">syncXStateToView</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  793. <span class="token keyword">if</span> <span class="token punctuation">(</span>x<span class="token punctuation">.</span>checked<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  794. y<span class="token punctuation">.</span>checked <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
  795. z<span class="token punctuation">.</span>value <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">;</span>
  796. <span class="token punctuation">}</span>
  797. <span class="token keyword">else</span> <span class="token punctuation">{</span>
  798. y<span class="token punctuation">.</span>checked <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
  799. <span class="token punctuation">}</span>
  800. <span class="token punctuation">}</span>
  801. <span class="token keyword">function</span> <span class="token function">checkAAvailability</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  802. <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>a<span class="token punctuation">.</span>value<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  803. <span class="token function">displayWarningForAMissing</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  804. <span class="token punctuation">}</span>
  805. <span class="token keyword">else</span> <span class="token punctuation">{</span>
  806. <span class="token function">clearWarnignForA</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  807. <span class="token punctuation">}</span>
  808. <span class="token punctuation">}</span>
  809. </code></pre></div><h4 id="_3-8-2-参数设计"><a href="#_3-8-2-参数设计" class="header-anchor">#</a> 3.8.2 参数设计</h4> <h5 id="【建议】-一个函数的参数控制在-6-个以内。"><a href="#【建议】-一个函数的参数控制在-6-个以内。" class="header-anchor">#</a> <strong>【建议】</strong> 一个函数的参数控制在 <code>6</code> 个以内。</h5> <p>解释:</p> <p>除去不定长参数以外,函数具备不同逻辑意义的参数建议控制在 6 个以内,过多参数会导致维护难度增大。</p> <h5 id="【建议】-通过-options-参数传递非数据输入型参数。"><a href="#【建议】-通过-options-参数传递非数据输入型参数。" class="header-anchor">#</a> <strong>【建议】</strong> 通过 <code>options</code> 参数传递非数据输入型参数。</h5> <p>解释:</p> <p>有些函数的参数并不是作为算法的输入,而是对算法的某些分支条件判断之用,此类参数建议通过一个 options 参数传递。</p> <p>如下函数:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">/**
  810. * 移除某个元素
  811. *
  812. * @param {Node} element 需要移除的元素
  813. * @param {boolean} removeEventListeners 是否同时将所有注册在元素上的事件移除
  814. */</span>
  815. <span class="token keyword">function</span> <span class="token function">removeElement</span><span class="token punctuation">(</span><span class="token parameter">element<span class="token punctuation">,</span> removeEventListeners</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  816. element<span class="token punctuation">.</span>parent<span class="token punctuation">.</span><span class="token function">removeChild</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">;</span>
  817. <span class="token keyword">if</span> <span class="token punctuation">(</span>removeEventListeners<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  818. element<span class="token punctuation">.</span><span class="token function">clearEventListeners</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  819. <span class="token punctuation">}</span>
  820. <span class="token punctuation">}</span>
  821. </code></pre></div><p>可以转换为下面的签名:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">/**
  822. * 移除某个元素
  823. *
  824. * @param {Node} element 需要移除的元素
  825. * @param {Object} options 相关的逻辑配置
  826. * @param {boolean} options.removeEventListeners 是否同时将所有注册在元素上的事件移除
  827. */</span>
  828. <span class="token keyword">function</span> <span class="token function">removeElement</span><span class="token punctuation">(</span><span class="token parameter">element<span class="token punctuation">,</span> options</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  829. element<span class="token punctuation">.</span>parent<span class="token punctuation">.</span><span class="token function">removeChild</span><span class="token punctuation">(</span>element<span class="token punctuation">)</span><span class="token punctuation">;</span>
  830. <span class="token keyword">if</span> <span class="token punctuation">(</span>options<span class="token punctuation">.</span>removeEventListeners<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  831. element<span class="token punctuation">.</span><span class="token function">clearEventListeners</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  832. <span class="token punctuation">}</span>
  833. <span class="token punctuation">}</span>
  834. </code></pre></div><p>这种模式有几个显著的优势:</p> <ul><li>boolean 型的配置项具备名称,从调用的代码上更易理解其表达的逻辑意义。</li> <li>当配置项有增长时,无需无休止地增加参数个数,不会出现 removeElement(element, true, false, false, 3) 这样难以理解的调用代码。</li> <li>当部分配置参数可选时,多个参数的形式非常难处理重载逻辑,而使用一个 options 对象只需判断属性是否存在,实现得以简化。</li></ul> <h4 id="_3-8-3-闭包"><a href="#_3-8-3-闭包" class="header-anchor">#</a> 3.8.3 闭包</h4> <h5 id="【建议】-在适当的时候将闭包内大对象置为-null。"><a href="#【建议】-在适当的时候将闭包内大对象置为-null。" class="header-anchor">#</a> <strong>【建议】</strong> 在适当的时候将闭包内大对象置为 <code>null</code>。</h5> <p>解释:</p> <p>在 JavaScript 中,无需特别的关键词就可以使用闭包,一个函数可以任意访问在其定义的作用域外的变量。需要注意的是,函数的作用域是静态的,即在定义时决定,与调用的时机和方式没有任何关系。</p> <p>闭包会阻止一些变量的垃圾回收,对于较老旧的JavaScript引擎,可能导致外部所有变量均无法回收。</p> <p>首先一个较为明确的结论是,以下内容会影响到闭包内变量的回收:</p> <ul><li>嵌套的函数中是否有使用该变量。</li> <li>嵌套的函数中是否有 <strong>直接调用eval</strong>。</li> <li>是否使用了 with 表达式。</li></ul> <p>Chakra、V8 和 SpiderMonkey 将受以上因素的影响,表现出不尽相同又较为相似的回收策略,而JScript.dll和Carakan则完全没有这方面的优化,会完整保留整个 LexicalEnvironment 中的所有变量绑定,造成一定的内存消耗。</p> <p>由于对闭包内变量有回收优化策略的 Chakra、V8 和 SpiderMonkey 引擎的行为较为相似,因此可以总结如下,当返回一个函数 fn 时:</p> <ol><li>如果 fn 的 [[Scope]] 是ObjectEnvironment(with 表达式生成 ObjectEnvironment,函数和 catch 表达式生成 DeclarativeEnvironment),则:
  835. <ol><li>如果是 V8 引擎,则退出全过程。</li> <li>如果是 SpiderMonkey,则处理该 ObjectEnvironment 的外层 LexicalEnvironment。</li></ol></li> <li>获取当前 LexicalEnvironment 下的所有类型为 Function 的对象,对于每一个 Function 对象,分析其 FunctionBody:
  836. <ol><li>如果 FunctionBody 中含有 <strong>直接调用eval</strong>,则退出全过程。</li> <li>否则得到所有的 Identifier。</li> <li>对于每一个 Identifier,设其为 name,根据查找变量引用的规则,从 LexicalEnvironment 中找出名称为 name 的绑定 binding。</li> <li>对 binding 添加 notSwap 属性,其值为 true。</li></ol></li> <li>检查当前 LexicalEnvironment 中的每一个变量绑定,如果该绑定有 notSwap 属性且值为 true,则:
  837. <ol><li>如果是V8引擎,删除该绑定。</li> <li>如果是SpiderMonkey,将该绑定的值设为 undefined,将删除 notSwap 属性。</li></ol></li></ol> <p>对于Chakra引擎,暂无法得知是按 V8 的模式还是按 SpiderMonkey 的模式进行。</p> <p>如果有 <strong>非常庞大</strong> 的对象,且预计会在 <strong>老旧的引擎</strong> 中执行,则使用闭包时,注意将闭包不需要的对象置为空引用。</p> <h5 id="【建议】-使用-iife-避免-lift-效应。"><a href="#【建议】-使用-iife-避免-lift-效应。" class="header-anchor">#</a> <strong>【建议】</strong> 使用 <code>IIFE</code> 避免 <code>Lift 效应</code>。</h5> <p>解释:</p> <p>在引用函数外部变量时,函数执行时外部变量的值由运行时决定而非定义时,最典型的场景如下:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">var</span> tasks <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  838. <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">5</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  839. tasks<span class="token punctuation">[</span>tasks<span class="token punctuation">.</span>length<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  840. console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Current cursor is at '</span> <span class="token operator">+</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>
  841. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  842. <span class="token punctuation">}</span>
  843. <span class="token keyword">var</span> len <span class="token operator">=</span> tasks<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
  844. <span class="token keyword">while</span> <span class="token punctuation">(</span>len<span class="token operator">--</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  845. tasks<span class="token punctuation">[</span>len<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  846. <span class="token punctuation">}</span>
  847. </code></pre></div><p>以上代码对 tasks 中的函数的执行均会输出 <code>Current cursor is at 5</code>,往往不符合预期。</p> <p>此现象称为 <strong>Lift 效应</strong> 。解决的方式是通过额外加上一层闭包函数,将需要的外部变量作为参数传递来解除变量的绑定关系:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">var</span> tasks <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  848. <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">5</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  849. <span class="token comment">// 注意有一层额外的闭包</span>
  850. tasks<span class="token punctuation">[</span>tasks<span class="token punctuation">.</span>length<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">i</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  851. <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  852. console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Current cursor is at '</span> <span class="token operator">+</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>
  853. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  854. <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
  855. <span class="token punctuation">}</span>
  856. <span class="token keyword">var</span> len <span class="token operator">=</span> tasks<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
  857. <span class="token keyword">while</span> <span class="token punctuation">(</span>len<span class="token operator">--</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  858. tasks<span class="token punctuation">[</span>len<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  859. <span class="token punctuation">}</span>
  860. </code></pre></div><h4 id="_3-8-4-空函数"><a href="#_3-8-4-空函数" class="header-anchor">#</a> 3.8.4 空函数</h4> <h5 id="【建议】-空函数不使用-new-function-的形式。"><a href="#【建议】-空函数不使用-new-function-的形式。" class="header-anchor">#</a> <strong>【建议】</strong> 空函数不使用 <code>new Function()</code> 的形式。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">var</span> <span class="token function-variable function">emptyFunction</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  861. </code></pre></div><h5 id="【建议】-对于性能有高要求的场合-建议存在一个空函数的常量-供多处使用共享。"><a href="#【建议】-对于性能有高要求的场合-建议存在一个空函数的常量-供多处使用共享。" class="header-anchor">#</a> <strong>【建议】</strong> 对于性能有高要求的场合,建议存在一个空函数的常量,供多处使用共享。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">var</span> <span class="token function-variable function">EMPTY_FUNCTION</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  862. <span class="token keyword">function</span> <span class="token function">MyClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  863. <span class="token punctuation">}</span>
  864. <span class="token class-name">MyClass</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>abstractMethod <span class="token operator">=</span> <span class="token constant">EMPTY_FUNCTION</span><span class="token punctuation">;</span>
  865. <span class="token class-name">MyClass</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>hooks<span class="token punctuation">.</span>before <span class="token operator">=</span> <span class="token constant">EMPTY_FUNCTION</span><span class="token punctuation">;</span>
  866. <span class="token class-name">MyClass</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>hooks<span class="token punctuation">.</span>after <span class="token operator">=</span> <span class="token constant">EMPTY_FUNCTION</span><span class="token punctuation">;</span>
  867. </code></pre></div><h3 id="_3-9-面向对象"><a href="#_3-9-面向对象" class="header-anchor">#</a> 3.9 面向对象</h3> <h5 id="【强制】-类的继承方案-实现时需要修正-constructor。"><a href="#【强制】-类的继承方案-实现时需要修正-constructor。" class="header-anchor">#</a> <strong>【强制】</strong> 类的继承方案,实现时需要修正 <code>constructor</code>。</h5> <p>解释:</p> <p>通常使用其他 library 的类继承方案都会进行 constructor 修正。如果是自己实现的类继承方案,需要进行 constructor 修正。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">/**
  868. * 构建类之间的继承关系
  869. *
  870. * @param {Function} subClass 子类函数
  871. * @param {Function} superClass 父类函数
  872. */</span>
  873. <span class="token keyword">function</span> <span class="token function">inherits</span><span class="token punctuation">(</span><span class="token parameter">subClass<span class="token punctuation">,</span> superClass</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  874. <span class="token keyword">var</span> <span class="token constant">F</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  875. <span class="token class-name">F</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> superClass<span class="token punctuation">.</span>prototype<span class="token punctuation">;</span>
  876. subClass<span class="token punctuation">.</span>prototype <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">F</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  877. subClass<span class="token punctuation">.</span>prototype<span class="token punctuation">.</span>constructor <span class="token operator">=</span> subClass<span class="token punctuation">;</span>
  878. <span class="token punctuation">}</span>
  879. </code></pre></div><h5 id="【建议】-声明类时-保证-constructor-的正确性。"><a href="#【建议】-声明类时-保证-constructor-的正确性。" class="header-anchor">#</a> <strong>【建议】</strong> 声明类时,保证 <code>constructor</code> 的正确性。</h5> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">function</span> <span class="token function">Animal</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  880. <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span>
  881. <span class="token punctuation">}</span>
  882. <span class="token comment">// 直接prototype等于对象时,需要修正constructor</span>
  883. <span class="token class-name">Animal</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> <span class="token punctuation">{</span>
  884. <span class="token literal-property property">constructor</span><span class="token operator">:</span> Animal<span class="token punctuation">,</span>
  885. <span class="token function-variable function">jump</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  886. <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">'animal '</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">+</span> <span class="token string">' jump'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  887. <span class="token punctuation">}</span>
  888. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  889. <span class="token comment">// 这种方式扩展prototype则无需理会constructor</span>
  890. <span class="token class-name">Animal</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">jump</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  891. <span class="token function">alert</span><span class="token punctuation">(</span><span class="token string">'animal '</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">+</span> <span class="token string">' jump'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  892. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  893. </code></pre></div><h5 id="【建议】-属性在构造函数中声明-方法在原型中声明。"><a href="#【建议】-属性在构造函数中声明-方法在原型中声明。" class="header-anchor">#</a> <strong>【建议】</strong> 属性在构造函数中声明,方法在原型中声明。</h5> <p>解释:</p> <p>原型对象的成员被所有实例共享,能节约内存占用。所以编码时我们应该遵守这样的原则:原型对象包含程序不会修改的成员,如方法函数或配置项。</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">function</span> <span class="token function">TextNode</span><span class="token punctuation">(</span><span class="token parameter">value<span class="token punctuation">,</span> engine</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  894. <span class="token keyword">this</span><span class="token punctuation">.</span>value <span class="token operator">=</span> value<span class="token punctuation">;</span>
  895. <span class="token keyword">this</span><span class="token punctuation">.</span>engine <span class="token operator">=</span> engine<span class="token punctuation">;</span>
  896. <span class="token punctuation">}</span>
  897. <span class="token class-name">TextNode</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">clone</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  898. <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span>
  899. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  900. </code></pre></div><h5 id="【强制】-自定义事件的-事件名-必须全小写。"><a href="#【强制】-自定义事件的-事件名-必须全小写。" class="header-anchor">#</a> <strong>【强制】</strong> 自定义事件的 <code>事件名</code> 必须全小写。</h5> <p>解释:</p> <p>在 JavaScript 广泛应用的浏览器环境,绝大多数 DOM 事件名称都是全小写的。为了遵循大多数 JavaScript 开发者的习惯,在设计自定义事件时,事件名也应该全小写。</p> <h5 id="【强制】-自定义事件只能有一个-event-参数。如果事件需要传递较多信息-应仔细设计事件对象。"><a href="#【强制】-自定义事件只能有一个-event-参数。如果事件需要传递较多信息-应仔细设计事件对象。" class="header-anchor">#</a> <strong>【强制】</strong> 自定义事件只能有一个 <code>event</code> 参数。如果事件需要传递较多信息,应仔细设计事件对象。</h5> <p>解释:</p> <p>一个事件对象的好处有:</p> <ol><li>顺序无关,避免事件监听者需要记忆参数顺序。</li> <li>每个事件信息都可以根据需要提供或者不提供,更自由。</li> <li>扩展方便,未来添加事件信息时,无需考虑会破坏监听器参数形式而无法向后兼容。</li></ol> <h5 id="【建议】-设计自定义事件时-应考虑禁止默认行为。"><a href="#【建议】-设计自定义事件时-应考虑禁止默认行为。" class="header-anchor">#</a> <strong>【建议】</strong> 设计自定义事件时,应考虑禁止默认行为。</h5> <p>解释:</p> <p>常见禁止默认行为的方式有两种:</p> <ol><li>事件监听函数中 return false。</li> <li>事件对象中包含禁止默认行为的方法,如 preventDefault。</li></ol> <h3 id="_3-10-动态特性"><a href="#_3-10-动态特性" class="header-anchor">#</a> 3.10 动态特性</h3> <h4 id="_3-10-1-eval"><a href="#_3-10-1-eval" class="header-anchor">#</a> 3.10.1 eval</h4> <h5 id="【强制】-避免使用直接-eval-函数。"><a href="#【强制】-避免使用直接-eval-函数。" class="header-anchor">#</a> <strong>【强制】</strong> 避免使用直接 <code>eval</code> 函数。</h5> <p>解释:</p> <p>直接 eval,指的是以函数方式调用 eval 的调用方法。直接 eval 调用执行代码的作用域为本地作用域,应当避免。</p> <p>如果有特殊情况需要使用直接 eval,需在代码中用详细的注释说明为何必须使用直接 eval,不能使用其它动态执行代码的方式,同时需要其他资深工程师进行 Code Review。</p> <h5 id="【建议】-尽量避免使用-eval-函数。"><a href="#【建议】-尽量避免使用-eval-函数。" class="header-anchor">#</a> <strong>【建议】</strong> 尽量避免使用 <code>eval</code> 函数。</h5> <h4 id="_3-10-2-动态执行代码"><a href="#_3-10-2-动态执行代码" class="header-anchor">#</a> 3.10.2 动态执行代码</h4> <h5 id="【建议】-使用-new-function-执行动态代码。"><a href="#【建议】-使用-new-function-执行动态代码。" class="header-anchor">#</a> <strong>【建议】</strong> 使用 <code>new Function</code> 执行动态代码。</h5> <p>解释:</p> <p>通过 new Function 生成的函数作用域是全局使用域,不会影响当当前的本地作用域。如果有动态代码执行的需求,建议使用 new Function。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">var</span> handler <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Function</span><span class="token punctuation">(</span><span class="token string">'x'</span><span class="token punctuation">,</span> <span class="token string">'y'</span><span class="token punctuation">,</span> <span class="token string">'return x + y;'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  901. <span class="token keyword">var</span> result <span class="token operator">=</span> <span class="token function">handler</span><span class="token punctuation">(</span><span class="token function">$</span><span class="token punctuation">(</span><span class="token string">'#x'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">val</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">'#y'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">val</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  902. </code></pre></div><h4 id="_3-10-3-with"><a href="#_3-10-3-with" class="header-anchor">#</a> 3.10.3 with</h4> <h5 id="【建议】-尽量不要使用-with。"><a href="#【建议】-尽量不要使用-with。" class="header-anchor">#</a> <strong>【建议】</strong> 尽量不要使用 <code>with</code>。</h5> <p>解释:</p> <p>使用 with 可能会增加代码的复杂度,不利于阅读和管理;也会对性能有影响。大多数使用 with 的场景都能使用其他方式较好的替代。所以,尽量不要使用 with。</p> <h4 id="_3-10-4-delete"><a href="#_3-10-4-delete" class="header-anchor">#</a> 3.10.4 delete</h4> <h5 id="【建议】-减少-delete-的使用。"><a href="#【建议】-减少-delete-的使用。" class="header-anchor">#</a> <strong>【建议】</strong> 减少 <code>delete</code> 的使用。</h5> <p>解释:</p> <p>如果没有特别的需求,减少或避免使用<code>delete</code>。<code>delete</code>的使用会破坏部分 JavaScript 引擎的性能优化。</p> <h5 id="【建议】-处理-delete-可能产生的异常。"><a href="#【建议】-处理-delete-可能产生的异常。" class="header-anchor">#</a> <strong>【建议】</strong> 处理 <code>delete</code> 可能产生的异常。</h5> <p>解释:</p> <p>对于有被遍历需求,且值 null 被认为具有业务逻辑意义的值的对象,移除某个属性必须使用 delete 操作。</p> <p>在严格模式或IE下使用 delete 时,不能被删除的属性会抛出异常,因此在不确定属性是否可以删除的情况下,建议添加 try-catch 块。</p> <p>示例:</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">try</span> <span class="token punctuation">{</span>
  903. <span class="token keyword">delete</span> o<span class="token punctuation">.</span>x<span class="token punctuation">;</span>
  904. <span class="token punctuation">}</span>
  905. <span class="token keyword">catch</span> <span class="token punctuation">(</span>deleteError<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  906. o<span class="token punctuation">.</span>x <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
  907. <span class="token punctuation">}</span>
  908. </code></pre></div><h4 id="_3-10-5-对象属性"><a href="#_3-10-5-对象属性" class="header-anchor">#</a> 3.10.5 对象属性</h4> <h5 id="【建议】-避免修改外部传入的对象。"><a href="#【建议】-避免修改外部传入的对象。" class="header-anchor">#</a> <strong>【建议】</strong> 避免修改外部传入的对象。</h5> <p>解释:</p> <p>JavaScript 因其脚本语言的动态特性,当一个对象未被 seal 或 freeze 时,可以任意添加、删除、修改属性值。</p> <p>但是随意地对 非自身控制的对象 进行修改,很容易造成代码在不可预知的情况下出现问题。因此,设计良好的组件、函数应该避免对外部传入的对象的修改。</p> <p>下面代码的 selectNode 方法修改了由外部传入的 datasource 对象。如果 datasource 用在其它场合(如另一个 Tree 实例)下,会造成状态的混乱。</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">function</span> <span class="token function">Tree</span><span class="token punctuation">(</span><span class="token parameter">datasource</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  909. <span class="token keyword">this</span><span class="token punctuation">.</span>datasource <span class="token operator">=</span> datasource<span class="token punctuation">;</span>
  910. <span class="token punctuation">}</span>
  911. <span class="token class-name">Tree</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">selectNode</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  912. <span class="token comment">// 从datasource中找出节点对象</span>
  913. <span class="token keyword">var</span> node <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">findNode</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
  914. <span class="token keyword">if</span> <span class="token punctuation">(</span>node<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  915. node<span class="token punctuation">.</span>selected <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
  916. <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">flushView</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  917. <span class="token punctuation">}</span>
  918. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  919. </code></pre></div><p>对于此类场景,需要使用额外的对象来维护,使用由自身控制,不与外部产生任何交互的 selectedNodeIndex 对象来维护节点的选中状态,不对 datasource 作任何修改。</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">function</span> <span class="token function">Tree</span><span class="token punctuation">(</span><span class="token parameter">datasource</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  920. <span class="token keyword">this</span><span class="token punctuation">.</span>datasource <span class="token operator">=</span> datasource<span class="token punctuation">;</span>
  921. <span class="token keyword">this</span><span class="token punctuation">.</span>selectedNodeIndex <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  922. <span class="token punctuation">}</span>
  923. <span class="token class-name">Tree</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">selectNode</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">id</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  924. <span class="token comment">// 从datasource中找出节点对象</span>
  925. <span class="token keyword">var</span> node <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">findNode</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
  926. <span class="token keyword">if</span> <span class="token punctuation">(</span>node<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  927. <span class="token keyword">this</span><span class="token punctuation">.</span>selectedNodeIndex<span class="token punctuation">[</span>id<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
  928. <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">flushView</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  929. <span class="token punctuation">}</span>
  930. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  931. </code></pre></div><p>除此之外,也可以通过 deepClone 等手段将自身维护的对象与外部传入的分离,保证不会相互影响。</p> <h5 id="【建议】-具备强类型的设计。"><a href="#【建议】-具备强类型的设计。" class="header-anchor">#</a> <strong>【建议】</strong> 具备强类型的设计。</h5> <p>解释:</p> <ul><li>如果一个属性被设计为 boolean 类型,则不要使用 1 / 0 作为其值。对于标识性的属性,如对代码体积有严格要求,可以从一开始就设计为 number 类型且将 0 作为否定值。</li> <li>从 DOM 中取出的值通常为 string 类型,如果有对象或函数的接收类型为 number 类型,提前作好转换,而不是期望对象、函数可以处理多类型的值。</li></ul> <h2 id="_4-浏览器环境"><a href="#_4-浏览器环境" class="header-anchor">#</a> 4 浏览器环境</h2> <h3 id="_4-1-dom"><a href="#_4-1-dom" class="header-anchor">#</a> 4.1 DOM</h3> <h4 id="_4-1-1-元素获取"><a href="#_4-1-1-元素获取" class="header-anchor">#</a> 4.1.1 元素获取</h4> <h5 id="【建议】-对于单个元素-尽可能使用-document-getelementbyid-获取-避免使用document-all。"><a href="#【建议】-对于单个元素-尽可能使用-document-getelementbyid-获取-避免使用document-all。" class="header-anchor">#</a> <strong>【建议】</strong> 对于单个元素,尽可能使用 <code>document.getElementById</code> 获取,避免使用<code>document.all</code>。</h5> <h5 id="【建议】-对于多个元素的集合-尽可能使用-context-getelementsbytagname-获取。其中-context-可以为-document-或其他元素。指定-tagname-参数为-可以获得所有子元素。"><a href="#【建议】-对于多个元素的集合-尽可能使用-context-getelementsbytagname-获取。其中-context-可以为-document-或其他元素。指定-tagname-参数为-可以获得所有子元素。" class="header-anchor">#</a> <strong>【建议】</strong> 对于多个元素的集合,尽可能使用 <code>context.getElementsByTagName</code> 获取。其中 <code>context</code> 可以为 <code>document</code> 或其他元素。指定 <code>tagName</code> 参数为 <code>*</code> 可以获得所有子元素。</h5> <h5 id="【建议】-遍历元素集合时-尽量缓存集合长度。如需多次操作同一集合-则应将集合转为数组。"><a href="#【建议】-遍历元素集合时-尽量缓存集合长度。如需多次操作同一集合-则应将集合转为数组。" class="header-anchor">#</a> <strong>【建议】</strong> 遍历元素集合时,尽量缓存集合长度。如需多次操作同一集合,则应将集合转为数组。</h5> <p>解释:</p> <p>原生获取元素集合的结果并不直接引用 DOM 元素,而是对索引进行读取,所以 DOM 结构的改变会实时反映到结果中。</p> <p>示例:</p> <div class="language-html extra-class"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  932. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span>
  933. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
  934. <span class="token keyword">var</span> elements <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementsByTagName</span><span class="token punctuation">(</span><span class="token string">'*'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  935. <span class="token comment">// 显示为 DIV</span>
  936. <span class="token function">alert</span><span class="token punctuation">(</span>elements<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>tagName<span class="token punctuation">)</span><span class="token punctuation">;</span>
  937. <span class="token keyword">var</span> div <span class="token operator">=</span> elements<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  938. <span class="token keyword">var</span> p <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">'p'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  939. docpment<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">insertBefore</span><span class="token punctuation">(</span>p<span class="token punctuation">,</span> div<span class="token punctuation">)</span><span class="token punctuation">;</span>
  940. <span class="token comment">// 显示为 P</span>
  941. <span class="token function">alert</span><span class="token punctuation">(</span>elements<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>tagName<span class="token punctuation">)</span><span class="token punctuation">;</span>
  942. </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
  943. </code></pre></div><h5 id="【建议】-获取元素的直接子元素时使用-children。避免使用childnodes-除非预期是需要包含文本、注释和属性类型的节点。"><a href="#【建议】-获取元素的直接子元素时使用-children。避免使用childnodes-除非预期是需要包含文本、注释和属性类型的节点。" class="header-anchor">#</a> <strong>【建议】</strong> 获取元素的直接子元素时使用 <code>children</code>。避免使用<code>childNodes</code>,除非预期是需要包含文本、注释和属性类型的节点。</h5> <h4 id="_4-1-2-样式获取"><a href="#_4-1-2-样式获取" class="header-anchor">#</a> 4.1.2 样式获取</h4> <h5 id="【建议】-获取元素实际样式信息时-应使用-getcomputedstyle-或-currentstyle。"><a href="#【建议】-获取元素实际样式信息时-应使用-getcomputedstyle-或-currentstyle。" class="header-anchor">#</a> <strong>【建议】</strong> 获取元素实际样式信息时,应使用 <code>getComputedStyle</code> 或 <code>currentStyle</code>。</h5> <p>解释:</p> <p>通过 style 只能获得内联定义或通过 JavaScript 直接设置的样式。通过 CSS class 设置的元素样式无法直接通过 style 获取。</p> <h4 id="_4-1-3-样式设置"><a href="#_4-1-3-样式设置" class="header-anchor">#</a> 4.1.3 样式设置</h4> <h5 id="【建议】-尽可能通过为元素添加预定义的-classname-来改变元素样式-避免直接操作-style-设置。"><a href="#【建议】-尽可能通过为元素添加预定义的-classname-来改变元素样式-避免直接操作-style-设置。" class="header-anchor">#</a> <strong>【建议】</strong> 尽可能通过为元素添加预定义的 className 来改变元素样式,避免直接操作 style 设置。</h5> <h5 id="【强制】-通过-style-对象设置元素样式时-对于带单位非-0-值的属性-不允许省略单位。"><a href="#【强制】-通过-style-对象设置元素样式时-对于带单位非-0-值的属性-不允许省略单位。" class="header-anchor">#</a> <strong>【强制】</strong> 通过 style 对象设置元素样式时,对于带单位非 0 值的属性,不允许省略单位。</h5> <p>解释:</p> <p>除了 IE,标准浏览器会忽略不规范的属性值,导致兼容性问题。</p> <h4 id="_4-1-4-dom-操作"><a href="#_4-1-4-dom-操作" class="header-anchor">#</a> 4.1.4 DOM 操作</h4> <h5 id="【建议】-操作-dom-时-尽量减少页面-reflow。"><a href="#【建议】-操作-dom-时-尽量减少页面-reflow。" class="header-anchor">#</a> <strong>【建议】</strong> 操作 <code>DOM</code> 时,尽量减少页面 <code>reflow</code>。</h5> <p>解释:</p> <p>页面 reflow 是非常耗时的行为,非常容易导致性能瓶颈。下面一些场景会触发浏览器的reflow:</p> <ul><li>DOM元素的添加、修改(内容)、删除。</li> <li>应用新的样式或者修改任何影响元素布局的属性。</li> <li>Resize浏览器窗口、滚动页面。</li> <li>读取元素的某些属性(offsetLeft、offsetTop、offsetHeight、offsetWidth、scrollTop/Left/Width/Height、clientTop/Left/Width/Height、getComputedStyle()、currentStyle(in IE)) 。</li></ul> <h5 id="【建议】-尽量减少-dom-操作。"><a href="#【建议】-尽量减少-dom-操作。" class="header-anchor">#</a> <strong>【建议】</strong> 尽量减少 <code>DOM</code> 操作。</h5> <p>解释:</p> <p>DOM 操作也是非常耗时的一种操作,减少 DOM 操作有助于提高性能。举一个简单的例子,构建一个列表。我们可以用两种方式:</p> <ol><li>在循环体中 createElement 并 append 到父元素中。</li> <li>在循环体中拼接 HTML 字符串,循环结束后写父元素的 innerHTML。</li></ol> <p>第一种方法看起来比较标准,但是每次循环都会对 DOM 进行操作,性能极低。在这里推荐使用第二种方法。</p> <h4 id="_4-1-5-dom-事件"><a href="#_4-1-5-dom-事件" class="header-anchor">#</a> 4.1.5 DOM 事件</h4> <h5 id="【建议】-优先使用-addeventlistener-attachevent-绑定事件-避免直接在-html-属性中或-dom-的-expando-属性绑定事件处理。"><a href="#【建议】-优先使用-addeventlistener-attachevent-绑定事件-避免直接在-html-属性中或-dom-的-expando-属性绑定事件处理。" class="header-anchor">#</a> <strong>【建议】</strong> 优先使用 <code>addEventListener / attachEvent</code> 绑定事件,避免直接在 HTML 属性中或 DOM 的 <code>expando</code> 属性绑定事件处理。</h5> <p>解释:</p> <p>expando 属性绑定事件容易导致互相覆盖。</p> <h5 id="【建议】-使用-addeventlistener-时第三个参数使用-false。"><a href="#【建议】-使用-addeventlistener-时第三个参数使用-false。" class="header-anchor">#</a> <strong>【建议】</strong> 使用 <code>addEventListener</code> 时第三个参数使用 <code>false</code>。</h5> <p>解释:</p> <p>标准浏览器中的 addEventListener 可以通过第三个参数指定两种时间触发模型:冒泡和捕获。而 IE 的 attachEvent 仅支持冒泡的事件触发。所以为了保持一致性,通常 addEventListener 的第三个参数都为 false。</p> <h5 id="【建议】-在没有事件自动管理的框架支持下-应持有监听器函数的引用-在适当时候-元素释放、页面卸载等-移除添加的监听器。"><a href="#【建议】-在没有事件自动管理的框架支持下-应持有监听器函数的引用-在适当时候-元素释放、页面卸载等-移除添加的监听器。" class="header-anchor">#</a> <strong>【建议】</strong> 在没有事件自动管理的框架支持下,应持有监听器函数的引用,在适当时候(元素释放、页面卸载等)移除添加的监听器。</h5></div> <footer class="page-edit"><!----> <!----></footer> <!----> </main></div><div class="global-ui"></div></div>
  944. <script src="/docs/assets/js/app.9d841bbb.js" defer></script><script src="/docs/assets/js/2.a7c99d38.js" defer></script><script src="/docs/assets/js/22.77e586e0.js" defer></script>
  945. </body>
  946. </html>