{"_id":"eslint-config-tencent","_rev":"16-31a63df4c7171a4c3edea92b2bc0e870","name":"eslint-config-tencent","dist-tags":{"latest":"1.2.0"},"versions":{"0.0.1-beta.1":{"name":"eslint-config-tencent","version":"0.0.1-beta.1","keywords":["npm-robbery"],"_id":"eslint-config-tencent@0.0.1-beta.1","maintainers":[{"name":"atool","email":"i@hust.cc"}],"dist":{"shasum":"a794055065a26af5d81234eeeba35a99a550c3ac","tarball":"https://registry.npmjs.org/eslint-config-tencent/-/eslint-config-tencent-0.0.1-beta.1.tgz","fileCount":2,"integrity":"sha512-JHT75J1uEADxfTWnDKlQy0idkHFZcVKXtZ0/95Eqzd/Sw24nXPcJRF6G7HwDZoExleYoE14Oh8ot993GRy6xKg==","signatures":[{"sig":"MEUCIC7cQpIeOAWCTw4TyeOST7QtI+2vXnaucKgVY+it/EZiAiEAvYwqttx94YQ8iV6A3+qAqKQ+AwgHq2wNQPm1CS342bg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":242,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdbxbgCRA9TVsSAnZWagAAysEP/1uqubTbp7wMGMKcFVuE\nWRKF13Afmx75OyCuIusteB1MlVwS0eRJdvv0H+5q8Vy1aOL6S/dMRwVWVPbi\nG7J+j+wQ0r6XbTfHj61TW5MGwhuqI2BT1vL95Z3JqCbztKSpfqtfIMONmd58\n78i7g3bgtyOIIsJLSKleencNYVMze9zTY1qdinDeWhH+5tcv89A0WJbwY3Jv\nJOu1whqD1+DoEjzTY2GHsKktSaUm29OTfaPEzD6Ajgah8JdvgBvlyCu00p5k\n5qMXhFCFMrjH4eH16z9RQMGEaSSvODlQxGnT0ado43YjOw0SAyu9XugDJSRz\n1ezG4G1hbn42Gd2lCdRvWb2Sz1/BCPj3IiESFg7kZmczW1QrE9594qr1wfEe\n/rMMMka4EF95wDVnvCXKX5QojyFopB1LrW0bH0hCJiJY3LegLz81wEOpLF2U\nLo4BjpkI+5XOGxbeNcPPTIyngTWrjkedeYkkwmImhLENW7X8NCH6RnuxeQBn\n8aEb6nko37jpPSFi8ARmz/h64+7aqbEnqQ9Yd3Yv29sRU5W0G0UQ8aRVrZAY\niE3Btaa1nE21SrpG4DDpvkr9Cpikpght1pIz/klFEE5AWnpYbqEdStmv4q6O\nnFw2KqX2T+tiLs0e3bs25zM+ZLM5wSVz4bW1BjcKiWdx3R2RNlmO4FIwpqCc\nDdCR\r\n=QZYt\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","_npmUser":{"name":"atool","email":"i@hust.cc"},"deprecated":"this package has been deprecated","_npmVersion":"6.7.0","description":"npm package name robbery.","directories":{},"_nodeVersion":"11.10.1","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/eslint-config-tencent_0.0.1-beta.1_1567561439407_0.20456772460489026","host":"s3://npm-registry-packages"}},"1.0.0":{"name":"eslint-config-tencent","version":"1.0.0","license":"SEE LICENSE IN LICENSE","_id":"eslint-config-tencent@1.0.0","maintainers":[{"name":"xcatliu","email":"xcatliu@gmail.com"},{"name":"xuqingkuang","email":"x@kxq.io"}],"dist":{"shasum":"757b041269c131a1f9fe06ca95b235c12719dfd2","tarball":"https://registry.npmjs.org/eslint-config-tencent/-/eslint-config-tencent-1.0.0.tgz","fileCount":8,"integrity":"sha512-rw2wCKnwuKsXGmD6PYiOkurzWGx0oLSsU349lLQP1o9B0IfeC1CDvoiwY8OzYOhvXOHfcI7QPVgiwqyfeXymkQ==","signatures":[{"sig":"MEUCIHNfAMbYjGq6K4zWveA+L00Hnkcg+wZjFoHKx7egnKnyAiEAkxit3n3QQKSQrOHSR3870LfTpeIc0iAZlersCw/879w=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":22328,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfVfgSCRA9TVsSAnZWagAAzsgP/0TXYNZvxUsvCiqEPOfx\nJU+szYMr49Skq6Pv8DwbONWDpOBnZTd+xE0dF60jU+o8qqSTXmLqhzfgJh3x\nDSg8bUW4GHQIkNoNq5qC6bzGU+zO2F7Z7h2f1XZowIQDaX2nxB7bLaQOVbAA\nlVxYgv6UwJZquTpGtkcqRGc7jnoFywTp65gstnXBLgpYl2nGDoT/llnBgOOB\nTOH9kmZCvetdTt5arVOiR43MTCbNoNl/58CEaB1yksbem9PmBmUpuhfZ96tQ\n0O9N4U/qj29Qnn3NvsXF4aMzjsUz5k4Q5/QWtZYl1k3IP9o5n1iueXFa/s4Z\njVnWXkoCTibRJhrKSvUdacU5y15ckiOaMtVj/bLcqGcZr6SBxwdFpjoDpiKF\n3/PWAJYES/pQP12LFdZ2QWVqOFI1bJq0UiQR9XVfNNv3lYwFKRkLURdt1E4H\nSzCk+978ZMNmKT5hMJDQAnMWfSRQkHpBYNy6GOaQZwKjZRxU5GtHgzGzyIg3\nwPX1aBEZ+WiZoolh6VsoCUvV3r+MFwCSK/BfrkrZnkHSzbaTuJlEXPWhZj7B\n8bN8DMYwU74bD7zWyENySXgbaeSOl8UzfKlvTAo+/jKdvzpidWxHtIUfLhbq\nbUlkhEO7WbS4VlQsG9D6FeV9nhewBkxilYUldjdXOJIzmevyJHY5BqJb2vKT\ngvq/\r\n=e8a2\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"4318c8dbde375d2dbbc3260652d5902898405aec","_npmUser":{"name":"xuqingkuang","email":"x@kxq.io"},"_npmVersion":"6.13.4","description":"a eslint config","directories":{},"_nodeVersion":"12.16.1","dependencies":{"babel-eslint":"^10.0.3","eslint-plugin-import":"^2.19.1"},"_hasShrinkwrap":false,"peerDependencies":{"eslint":"^6.8.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-config-tencent_1.0.0_1599469586415_0.8324777801578287","host":"s3://npm-registry-packages"}},"1.0.1":{"name":"eslint-config-tencent","version":"1.0.1","license":"SEE LICENSE IN LICENSE","_id":"eslint-config-tencent@1.0.1","maintainers":[{"name":"xcatliu","email":"xcatliu@gmail.com"},{"name":"xuqingkuang","email":"x@kxq.io"}],"dist":{"shasum":"46369c58dd28c053603143da2396c89f1f614bab","tarball":"https://registry.npmjs.org/eslint-config-tencent/-/eslint-config-tencent-1.0.1.tgz","fileCount":10,"integrity":"sha512-2KzqvRSFQSUzBwIPXW0POIKC6H3wz3MOFsFAyv5GkUJ8z42xq863f9OJY7VEC1mcxzn1MW3wC03c1vt91X1vCQ==","signatures":[{"sig":"MEQCIDOH5NpTQ+c53NXQ4ysHmWxCHYRsNK9XkuS1YCh0HaazAiBPqqLwNpEg7sus9dK0JfoSqKI0BVXQOJ3qZD/xgsR/zw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":30171,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgzG1iCRA9TVsSAnZWagAAjkgP/0rZLGzdp4iFtEhWSHPX\ngQcJ6/4HZUm6gGp9frtZ02As7GExqV10cozbsUzF7e0kBJ77P/eGLr9ZfNv0\nBQnv/E0GCfI20XiaCEf5QQnoUWJgaiS4C0x1j0EG0ZURL81XbQty4HEBhc0P\nl3/cJk6cnb7z+PBZpyMOHhzlQ8F+lmf2S76KtGhQ86IMjiIpk2uteJT4w/WN\nylPgD+FcKujHVYR/QhGT2GmLJCQx9KtaVRuQEG4RM8ZN9rHzUpxVuShFrcIp\nFy3hF+SSFcH0jqMk53ibd7oy5OA3ayCnWelt7y9wWr/oiRdAZl1kFP+WKKmy\niIAlAjzuqit5bXkOEHR1QWZLpmOomYYxCqOVs/6AxKt4Ikr8upibqrWBMD+A\njTAZMPTwMaFlP6Qc1BudoZ14XsJm7wgWFwkrUKanlGthcroo9TyCqFLITF6B\nMTReenwpXSHW03mSFDhOTlHojcPSvoTJ3EAvtzxyR36EWec0F5wq4n72KYlS\nM3Cc9dd9Rovn+TqgqhV+OU4zOgb9TiL30FppHRspU42EEuI7SsW6ziA4YLYQ\nlDCwh1N2/yitTCKgrUCX/DNRgS/KSiA/FCHrQQjMe30u8Y3xcqH7PnSXU3CI\nSEGOLo13mxk577HY9AAatsFmFQYMyWr5Xi05kusvgFw69WFgxLxa2iBXwD/h\nIAj5\r\n=dMco\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"5fe92c32135d381b9a1ab74be92e0ccfb729182a","_npmUser":{"name":"xuqingkuang","email":"x@kxq.io"},"_npmVersion":"7.15.1","description":"a eslint config","directories":{},"_nodeVersion":"14.17.0","dependencies":{"@babel/eslint-parser":"^7.14.5","eslint-plugin-import":"^2.23.4"},"_hasShrinkwrap":false,"peerDependencies":{"eslint":"^7.28.0","prettier":"^2.3.1","@babel/core":"^7.14.6","eslint-plugin-prettier":"^3.4.0","@typescript-eslint/parser":"^4.27.0","@typescript-eslint/eslint-plugin":"^4.27.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-config-tencent_1.0.1_1624010081704_0.4865288524638285","host":"s3://npm-registry-packages"}},"1.0.2":{"name":"eslint-config-tencent","version":"1.0.2","license":"SEE LICENSE IN LICENSE","_id":"eslint-config-tencent@1.0.2","maintainers":[{"name":"xcatliu","email":"xcatliu@gmail.com"},{"name":"xuqingkuang","email":"x@kxq.io"}],"dist":{"shasum":"2bf1d712f0e216fface458ab798203f2bbd5c023","tarball":"https://registry.npmjs.org/eslint-config-tencent/-/eslint-config-tencent-1.0.2.tgz","fileCount":10,"integrity":"sha512-QmUMMtJJ2ohvEaYI6QEU9noFJZMiH3dIrImLVvdR+mIpA5sfSGoLgb2vmKXqJKymqR2vmGg+cAlNnXEgIFHQwA==","signatures":[{"sig":"MEUCIGher7EqtJUXlc/gOylGf8l18l24p3fDX8qSJAjqpVKUAiEAtUxhdKIu7+xmeAJbVjR6MrpPWUAywRk2c14Qyn6+oF4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":28212,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg2UmDCRA9TVsSAnZWagAA8mcP/2ZOKCestABF+9ZoGIWQ\nmvPEfU0Sn+B5oSoEm1Weh2IdGQWkHS11MsDcUVpRClbRkHiXDy7VNUhhkKZ/\nxKXYEXlm+WX6Uo8gXb8nYkLCEmu4EZJDFgGmC/xfLiLHxC6wNItu1Z7LfYE8\nr9JRLUfh0o8j0XdhCglR+Jiy7fVX+QW8C10wJZun6tSaFmXL65m5gFizoRlF\noIUVCP8mLIcT9JpSFXPEvrmPOWkMW/53Wf/CrBMarNpXlcoHUQLUWi1iRdWR\nfxW4s9dhHxXV+WBZiQFv0oldvmFT6ar4SO9nIfLODGgufov0lVNrpexeV0CP\n+nl/pmVit8C7fX9JBIe+cSeZ8Ag4eLV5fid0ckaLm6vI64A8p2GfBG/03EJn\n6z9s3o+G1TsbyLuSS5fqg5i3vWP9aRq1uTZ0OqingdggIbmp5RKHMK2KXRqE\nPGAEmmrMWzbAHgWPkmplX5JEQy6gzEev7a1kl2+OBhlacltDnoI4/WLXv/9F\nAt2ttMmt6C1ZZkg9/ONktDMIRGZ3VBciVYZncnQSBUSWiisyaTStLd0/y7CJ\nmaWzf7Rv7FPPS2eVfnGkZk4w5bDerdXaPH/jl25mMJ/HpdsnDNTQ0o2Atznu\n7x6elQeKUZIq9sajgvSG4qDen/S6ttIgLN5waqIz/+pNSG0A1UpywcvjoVSa\nhIvq\r\n=Gpwd\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","_npmUser":{"name":"xuqingkuang","email":"x@kxq.io"},"_npmVersion":"7.15.1","description":"a eslint config","directories":{},"_nodeVersion":"14.17.0","dependencies":{"@babel/eslint-parser":"^7.14.5","eslint-plugin-import":"^2.23.4"},"_hasShrinkwrap":false,"peerDependencies":{"eslint":"^7.28.0","prettier":"^2.3.1","@babel/core":"^7.14.6","eslint-plugin-prettier":"^3.4.0","@typescript-eslint/parser":"^4.27.0","@typescript-eslint/eslint-plugin":"^4.27.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-config-tencent_1.0.2_1624852866638_0.7541156434341045","host":"s3://npm-registry-packages"}},"1.0.3":{"name":"eslint-config-tencent","version":"1.0.3","license":"UNLICENSED","_id":"eslint-config-tencent@1.0.3","maintainers":[{"name":"xcatliu","email":"xcatliu@gmail.com"},{"name":"xuqingkuang","email":"x@kxq.io"}],"dist":{"shasum":"8f4cb2b2a3e12ba17aefca600aacaecc98efaa14","tarball":"https://registry.npmjs.org/eslint-config-tencent/-/eslint-config-tencent-1.0.3.tgz","fileCount":10,"integrity":"sha512-h7M8+L6g/RUKZRujWEw5suzO/+ZfxLs27Y1/bNQkalanOMqRS1N5WopQ2kydPc7RNwQ+24q9vKnx6VhgSJBiUw==","signatures":[{"sig":"MEUCIQD7TrJu8M7B+39xwAvbIaili5D01bU769JoptztrF37aAIgYswZpaoqxBAxdSwtZYlha8rvsIPHizcpaReNO21wFnE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":13597,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiDgcUACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp9Dg/8CqxchjTJ8+bF/dGIL7266RSfQzYAJWwnLuzGzkNx9WOqh4q6\r\nUIIAuZpwe/+Qc5otqX5KHnWq3M9FUxdKYhO2szjUmFQ0n8eS6NjRoe2Ai80E\r\njZXUXIpLQOoqxa1fqUQ9ZBO4pBgTt8FNRP/q7js//zRULWnb3yJiHN6EapG5\r\nMDyygbVkBzBYtsH3vFq3kLbDz+gP1rEoGAnA0EpwGuOa9+VwD6mr4+LOuB43\r\nRviGMioGciNFdUEzevz2ZuY0cXVL4HQt5gzTIAbUGVwx1e/dLjtnlsLZ7ceO\r\n9qitZQGqpMeNoAegRAA9Tj1xWl1I7500IdBH3+pY+uMZe7QCYhOZidWO3VUM\r\n65hATSXgHe+wB9rUQA5MVkfdWp/n/d8zAUwHCSANCFO+0mzHWAYQBGprSYWS\r\nk+voKIi5NnK0sQFcJ4sorXfqqHub+UW9yWCBkp3QHK2e7w4BpIb4yar5ZnkF\r\ny02vPxGXhzm+SuIgseCTY2QUZTY8LsXWwmfssAPiO1/iBNS9E5cc/zt/E319\r\nx3yJO+eIB/VN3V+XKd9wRTs0ab2t/uqt4FYuYCp6+YdxbtCiwUiegq1+Oz42\r\nmRjoTc/RSwZiAR+DR775Qn0W8+9hV/7d/vUAwfkAU0hTdaJOvHIUfzOpe4Kb\r\n/D3dZFfc5I9rAADB9G/jMx8CuoQbQocYk1E=\r\n=pCXI\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"21a253ff8025c7e1d58e8d75896e06cbe7a63760","_npmUser":{"name":"xuqingkuang","email":"x@kxq.io"},"_npmVersion":"8.1.4","description":"a eslint config","directories":{},"_nodeVersion":"14.17.0","dependencies":{"@babel/eslint-parser":"^7.14.5","eslint-plugin-import":"^2.23.4"},"_hasShrinkwrap":false,"peerDependencies":{"eslint":"^7.28.0 || ^8.0.0","prettier":"^2.3.1","@babel/core":"^7.14.6","eslint-plugin-prettier":"^3.4.0 || ^4.0.0","@typescript-eslint/parser":"^4.27.0 || ^5.12.0","@typescript-eslint/eslint-plugin":"^4.27.0 || ^5.12.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-config-tencent_1.0.3_1645086484442_0.18075209426780292","host":"s3://npm-registry-packages"}},"1.0.4":{"name":"eslint-config-tencent","version":"1.0.4","license":"UNLICENSED","_id":"eslint-config-tencent@1.0.4","maintainers":[{"name":"xcatliu","email":"xcatliu@gmail.com"},{"name":"xuqingkuang","email":"x@kxq.io"}],"dist":{"shasum":"3196811af942202350c57f67ef0b6e81eaf9bcd3","tarball":"https://registry.npmjs.org/eslint-config-tencent/-/eslint-config-tencent-1.0.4.tgz","fileCount":10,"integrity":"sha512-h8r5f4iUdF5RyfIhOA+KXVAokltyUs4sGnYrzbY6bSZvUzYS282C2s4z3AYA8DCBfDaKPtUsDBOF+tEy38wTyA==","signatures":[{"sig":"MEUCIDR2K1xPaytnamD5ORTlcdlL4Y0WINtXrGXp2ilUky66AiEA3gEdYHwvY7mcIcKm5oqtuDZyJI8f8jzP8x+TyHoNYbA=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":13813,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiQ8thACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr29g//d5ViaNAy2MwKqnLZAr6KY7Q16jv34hCvo959Dsmvvmtzjnkd\r\nF9mRucTgN9Ss7f0W0DWUW6r7MAFvmPL7kst6p7ZPQk1oNJZfQxRjDGq43hk0\r\n3uhyKKoVporultVnqQpIf+pwP073uAOTvExqqpjNhu7d8YMxWOUMxNxEpRGY\r\nxsDQigr8Ht2RvciwqPHN+p+lx5UJLfbgBVxX8zP+JEACdndBpvhmypyrlk1u\r\n+RWB8SDKn3mFqo3TvDymV54liO6q75MAtrxkpMrWs8FsaPUYsIo18VHbXkEU\r\nXJ847OIn5EDa5rgicbcSR5tNdI9SSAnav7Qgy5WHC0DE86bIsmY7DKrLgW7K\r\nsZEg5olORGmaVut9CleCDhq5MDFtvFXji664kE/Gx/NI5WA0ED4QLXPOee4j\r\nR4CokA7kBVsVhPXCulYu1hv0EB6qdWXnZALSpmQ4FrplHD5p9bNiB7nAXhGW\r\nTQbnYgSZ605PWHgXTlKRq3mn0Vu6zE22I/MhuZtSWrhg3vVPVvMGRPmZOgtI\r\nZceRLjzKn+TNnus/JDZwtWoQT28e/Exg0SpUTI6t7acBdnITEU2Sqe94d+q9\r\nLH5z6vcibT+nsKAAbTEp8KHPFMqUb/+4X1IM4EthxQGqL7bEDewcgwfycOdS\r\nNeNFCyZyqne8nwy877xeSsFlcg5kQKN2EYA=\r\n=00he\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"4645be4310c04727052debaf9f96fd1dfc8f4010","_npmUser":{"name":"xuqingkuang","email":"x@kxq.io"},"_npmVersion":"8.3.1","description":"a eslint config","directories":{},"_nodeVersion":"14.19.0","dependencies":{"eslint-plugin-chalk":"^1.0.0","@babel/eslint-parser":"^7.14.5","eslint-plugin-import":"^2.23.4"},"_hasShrinkwrap":false,"peerDependencies":{"eslint":"^7.28.0 || ^8.0.0","prettier":"^2.3.1","@babel/core":"^7.14.6","eslint-plugin-prettier":"^3.4.0 || ^4.0.0","@typescript-eslint/parser":"^4.27.0 || ^5.12.0","@typescript-eslint/eslint-plugin":"^4.27.0 || ^5.12.0"},"_npmOperationalInternal":{"tmp":"tmp/eslint-config-tencent_1.0.4_1648610145438_0.4498616841532721","host":"s3://npm-registry-packages"}},"1.1.0":{"name":"eslint-config-tencent","version":"1.1.0","keywords":["eslint","eslintrc","eslintconfig","config","tencent","javascript","styleguide","react","vue","typescript"],"author":"","license":"MIT","_id":"eslint-config-tencent@1.1.0","maintainers":[{"name":"xcatliu","email":"xcatliu@gmail.com"},{"name":"xuqingkuang","email":"x@kxq.io"},{"name":"ziofat","email":"printlts@gmail.com"}],"contributors":[{"name":"xcatliu","email":"xcaliu@tencent.com"},{"name":"ziofatli"}],"homepage":"https://git.code.oa.com/standards/javascript","dist":{"shasum":"b0937b56b04426d8fb5cd95008e668b212fad57f","tarball":"https://registry.npmjs.org/eslint-config-tencent/-/eslint-config-tencent-1.1.0.tgz","fileCount":20,"integrity":"sha512-u8EiDyNUPjODhTjU9DlTYHdQTQ/8uG5UqYH+f1rD2uPy6awmWRZN1MDjRLQgB5gho7up2fj4b3q0MmSYF0sUbQ==","signatures":[{"sig":"MEUCIQD86G4qoSTE86GmxFR7BqEJ9FV5QOTaXKexueJruoMt6QIgYG3rBOG6OGZIW80eJnYxc1fe8lvQjBTrSMRefIR/5tc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":191397},"main":"index.js","exports":{".":"./index.js","./flat":"./flat/index.js"},"gitHead":"eda96b6c1132782d425d4deb393544cc14868981","scripts":{"dev":"run-p dev:eslintrc dev:site","lint":"run-s eslint markdownlint","test":"npm run lint && ts-node ./test/index.ts","build":"run-s build:eslintrc build:site","start":"npm run dev","eslint":"eslint ./test --ext .js,.jsx,.ts,.tsx,.vue --ignore-pattern \"bad.*\" .","autotag":"node ./scripts/autoTag.js","dev:site":"parcel site/index.html --out-dir .cache","build:html":"parcel build site/index.html --public-url ./","build:site":"run-s clear:dist build:html","clear:dist":"rimraf ./dist","dev:eslintrc":"nodemon","markdownlint":"markdownlint --config ./.markdownlintrc.json README.md","build:eslintrc":"ts-node scripts/build.ts","test:rulesCoverage":"ts-node ./scripts/rulesCoverage.ts"},"_npmUser":{"name":"ziofat","email":"printlts@gmail.com"},"repository":{"url":"https://git.woa.com/standards/javascript.git","type":"git"},"_npmVersion":"10.5.0","description":"ESLint Config for Tencent","directories":{},"_nodeVersion":"18.20.2","dependencies":{"@eslint/js":"^8.57.0","eslint-plugin-vue":"^9.24.0","typescript-eslint":"^7.18.0","eslint-plugin-chalk":"^1.0.0","eslint-plugin-react":"^7.35.0","@babel/eslint-parser":"^7.14.5","eslint-plugin-import":"^2.31.0","eslint-plugin-prettier":"^3.4.0"},"_hasShrinkwrap":false,"devDependencies":{"husky":"^6.0.0","react":"^17.0.2","cookie":"^0.4.1","eslint":"^8.57.0","rimraf":"^3.0.2","nodemon":"^2.0.7","ts-node":"^10.0.0","doctrine":"^3.0.0","mobi.css":"^3.1.1","prettier":"^2.3.1","react-dom":"^17.0.2","insert-tag":"^0.1.2","typescript":"^4.3.2","xml-escape":"^1.1.0","@types/node":"^18.15.3","npm-run-all":"^4.1.5","@types/react":"^17.0.11","browserslist":"^4.17.6","@types/cookie":"^0.4.0","@types/eslint":"^8.44.2","@types/rimraf":"^3.0.0","react-tooltip":"^4.2.21","parcel-bundler":"^1.12.4","@types/doctrine":"0.0.3","@types/react-dom":"^17.0.7","markdownlint-cli":"^0.27.1","semantic-release":"^17.4.4","@types/eslint__js":"^8.42.3","@types/xml-escape":"^1.1.0","mobi-plugin-color":"^1.0.0","vue-eslint-parser":"^7.6.0","@types/react-tooltip":"^3.11.0"},"peerDependencies":{"eslint":">= 7.28.0 < 10.0.0","@babel/core":"^7.14.6"},"_npmOperationalInternal":{"tmp":"tmp/eslint-config-tencent_1.1.0_1729517711721_0.02412390777598672","host":"s3://npm-registry-packages"}},"1.1.1":{"name":"eslint-config-tencent","version":"1.1.1","keywords":["eslint","eslintrc","eslintconfig","config","tencent","javascript","styleguide","react","vue","typescript"],"author":"","license":"MIT","_id":"eslint-config-tencent@1.1.1","maintainers":[{"name":"xcatliu","email":"xcatliu@gmail.com"},{"name":"xuqingkuang","email":"x@kxq.io"},{"name":"ziofat","email":"printlts@gmail.com"}],"contributors":[{"name":"xcatliu","email":"xcaliu@tencent.com"},{"name":"ziofatli"}],"homepage":"https://git.code.oa.com/standards/javascript","dist":{"shasum":"887708fb7d9481b993ba779d9013f81b55ecae32","tarball":"https://registry.npmjs.org/eslint-config-tencent/-/eslint-config-tencent-1.1.1.tgz","fileCount":20,"integrity":"sha512-GJHjCo9/cCjmDxuG8Mu0OoQA4YKZdozm5q1tgzgoSw3TJUBo1HFcFAWd5bpi4ZrxuZrsZram9uvx9R66YfIoRQ==","signatures":[{"sig":"MEUCIQDqrDpA7LWVI+FrlGH8kGAJsibxymvIlnZdvl9BoeWdlQIgcYVni0yPMIAU3cBBKF4zGnmgUZ2WWVDmDnE5uBXR5d8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":191620},"main":"index.js","exports":{".":"./index.js","./ts":"./ts.js","./base":"./base.js","./flat":"./flat/index.js","./react":"./react.js","./import":"./import.js","./prettier":"./prettier.js","./ts-legacy":"./ts-legacy.js","./base-legacy":"./base-legacy.js"},"gitHead":"eda96b6c1132782d425d4deb393544cc14868981","scripts":{"dev":"run-p dev:eslintrc dev:site","lint":"run-s eslint markdownlint","test":"npm run lint && ts-node ./test/index.ts","build":"run-s build:eslintrc build:site","start":"npm run dev","eslint":"eslint ./test --ext .js,.jsx,.ts,.tsx,.vue --ignore-pattern \"bad.*\" .","autotag":"node ./scripts/autoTag.js","dev:site":"parcel site/index.html --out-dir .cache","build:html":"parcel build site/index.html --public-url ./","build:site":"run-s clear:dist build:html","clear:dist":"rimraf ./dist","dev:eslintrc":"nodemon","markdownlint":"markdownlint --config ./.markdownlintrc.json README.md","build:eslintrc":"ts-node scripts/build.ts","test:rulesCoverage":"ts-node ./scripts/rulesCoverage.ts"},"_npmUser":{"name":"ziofat","email":"printlts@gmail.com"},"repository":{"url":"https://git.woa.com/standards/javascript.git","type":"git"},"_npmVersion":"10.5.0","description":"ESLint Config for Tencent","directories":{},"_nodeVersion":"18.20.2","dependencies":{"@eslint/js":"^8.57.0","eslint-plugin-vue":"^9.24.0","typescript-eslint":"^7.18.0","eslint-plugin-chalk":"^1.0.0","eslint-plugin-react":"^7.35.0","@babel/eslint-parser":"^7.14.5","eslint-plugin-import":"^2.31.0","eslint-plugin-prettier":"^3.4.0"},"_hasShrinkwrap":false,"devDependencies":{"husky":"^6.0.0","react":"^17.0.2","cookie":"^0.4.1","eslint":"^8.57.0","rimraf":"^3.0.2","nodemon":"^2.0.7","ts-node":"^10.0.0","doctrine":"^3.0.0","mobi.css":"^3.1.1","prettier":"^2.3.1","react-dom":"^17.0.2","insert-tag":"^0.1.2","typescript":"^4.3.2","xml-escape":"^1.1.0","@types/node":"^18.15.3","npm-run-all":"^4.1.5","@types/react":"^17.0.11","browserslist":"^4.17.6","@types/cookie":"^0.4.0","@types/eslint":"^8.44.2","@types/rimraf":"^3.0.0","react-tooltip":"^4.2.21","parcel-bundler":"^1.12.4","@types/doctrine":"0.0.3","@types/react-dom":"^17.0.7","markdownlint-cli":"^0.27.1","semantic-release":"^17.4.4","@types/eslint__js":"^8.42.3","@types/xml-escape":"^1.1.0","mobi-plugin-color":"^1.0.0","vue-eslint-parser":"^7.6.0","@types/react-tooltip":"^3.11.0"},"peerDependencies":{"eslint":">= 7.28.0 < 10.0.0","@babel/core":"^7.14.6"},"_npmOperationalInternal":{"tmp":"tmp/eslint-config-tencent_1.1.1_1729578218334_0.46795804046825085","host":"s3://npm-registry-packages"}},"1.1.2":{"name":"eslint-config-tencent","version":"1.1.2","keywords":["eslint","eslintrc","eslintconfig","config","tencent","javascript","styleguide","react","vue","typescript"],"author":"","license":"MIT","_id":"eslint-config-tencent@1.1.2","maintainers":[{"name":"xcatliu","email":"xcatliu@gmail.com"},{"name":"xuqingkuang","email":"x@kxq.io"},{"name":"ziofat","email":"printlts@gmail.com"}],"contributors":[{"name":"xcatliu","email":"xcaliu@tencent.com"},{"name":"ziofatli"}],"homepage":"https://git.code.oa.com/standards/javascript","dist":{"shasum":"a9383b5096bbf01ad983d1a7f99fe60c289a8690","tarball":"https://registry.npmjs.org/eslint-config-tencent/-/eslint-config-tencent-1.1.2.tgz","fileCount":20,"integrity":"sha512-dUww15dl168Lobeev8qU87hNITN7mFTCs+Ftr3UFQHhzEHm2BVb2ieg/ABV2yji/H/vsrGBCGIcqUT/R3XcxxQ==","signatures":[{"sig":"MEUCIA+9WLR/KdWCfqH4bQcS4dvyZ2WyXS7FNr2uWT22bwAoAiEA78vwpLhNE0cl2YmDwrkbipBOEdAzMD5NTCSm25WmWA0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":191639},"main":"index.js","exports":{".":"./index.js","./ts":"./ts.js","./base":"./base.js","./flat":"./flat/index.js","./react":"./react.js","./import":"./import.js","./prettier":"./prettier.js","./ts-legacy":"./ts-legacy.js","./base-legacy":"./base-legacy.js"},"gitHead":"57cfda84629670ec3c7d5ec56497cbf7c329925d","scripts":{"dev":"run-p dev:eslintrc dev:site","lint":"run-s eslint markdownlint","test":"npm run lint && ts-node ./test/index.ts","build":"run-s build:eslintrc build:site","start":"npm run dev","eslint":"eslint ./test --ext .js,.jsx,.ts,.tsx,.vue --ignore-pattern \"bad.*\" .","autotag":"node ./scripts/autoTag.js","dev:site":"parcel site/index.html --out-dir .cache","build:html":"parcel build site/index.html --public-url ./","build:site":"run-s clear:dist build:html","clear:dist":"rimraf ./dist","dev:eslintrc":"nodemon","markdownlint":"markdownlint --config ./.markdownlintrc.json README.md","build:eslintrc":"ts-node scripts/build.ts","test:rulesCoverage":"ts-node ./scripts/rulesCoverage.ts"},"_npmUser":{"name":"ziofat","email":"printlts@gmail.com"},"repository":{"url":"https://git.woa.com/standards/javascript.git","type":"git"},"_npmVersion":"10.8.2","description":"ESLint Config for Tencent","directories":{},"_nodeVersion":"20.17.0","dependencies":{"@eslint/js":"^8.57.0","eslint-plugin-vue":"^9.24.0","typescript-eslint":"^7.18.0","eslint-plugin-chalk":"^1.0.0","eslint-plugin-react":"^7.35.0","@babel/eslint-parser":"^7.14.5","eslint-plugin-import":"^2.31.0","eslint-plugin-prettier":"^3.4.0"},"_hasShrinkwrap":false,"devDependencies":{"husky":"^6.0.0","react":"^17.0.2","cookie":"^0.4.1","eslint":"^8.57.0","rimraf":"^3.0.2","nodemon":"^2.0.7","ts-node":"^10.0.0","doctrine":"^3.0.0","mobi.css":"^3.1.1","prettier":"^2.3.1","react-dom":"^17.0.2","insert-tag":"^0.1.2","typescript":"^4.3.2","xml-escape":"^1.1.0","@types/node":"^18.15.3","npm-run-all":"^4.1.5","@types/react":"^17.0.11","browserslist":"^4.17.6","@types/cookie":"^0.4.0","@types/eslint":"^8.44.2","@types/rimraf":"^3.0.0","react-tooltip":"^4.2.21","parcel-bundler":"^1.12.4","@types/doctrine":"0.0.3","@types/react-dom":"^17.0.7","markdownlint-cli":"^0.27.1","semantic-release":"^17.4.4","@types/eslint__js":"^8.42.3","@types/xml-escape":"^1.1.0","mobi-plugin-color":"^1.0.0","vue-eslint-parser":"^7.6.0","@types/react-tooltip":"^3.11.0"},"peerDependencies":{"eslint":">= 7.28.0 < 10.0.0","@babel/core":"^7.14.6"},"_npmOperationalInternal":{"tmp":"tmp/eslint-config-tencent_1.1.2_1734588886548_0.31522826485519584","host":"s3://npm-registry-packages-npm-production"}},"1.1.3":{"name":"eslint-config-tencent","version":"1.1.3","keywords":["eslint","eslintrc","eslintconfig","config","tencent","javascript","styleguide","react","vue","typescript"],"author":"","license":"MIT","_id":"eslint-config-tencent@1.1.3","maintainers":[{"name":"xcatliu","email":"xcatliu@gmail.com"},{"name":"xuqingkuang","email":"x@kxq.io"},{"name":"ziofat","email":"printlts@gmail.com"}],"contributors":[{"name":"xcatliu","email":"xcaliu@tencent.com"},{"name":"ziofatli"}],"dist":{"shasum":"bd0bb4bb815b78ea7af7b07a6d4fb1731d628475","tarball":"https://registry.npmjs.org/eslint-config-tencent/-/eslint-config-tencent-1.1.3.tgz","fileCount":20,"integrity":"sha512-8RAev4+j2kJ3YzXbrQ032fYV4q49AW7b1FeeZ2NXBcL8xt6asA1n5NPuPCAM8PKFHYLb2SBSv8x0blDkm6UU4g==","signatures":[{"sig":"MEQCIAE0p+5uJbdAhj5cfJvCuT89kB8hRE4732hbl+SdSzfBAiAePBUedSpPJbGrSIoGD5C0cfCgRWXUx4eQpp+jok8DeA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":198034},"main":"index.js","exports":{".":"./index.js","./ts":"./ts.js","./base":"./base.js","./flat":"./flat/index.js","./react":"./react.js","./import":"./import.js","./prettier":"./prettier.js","./ts-legacy":"./ts-legacy.js","./base-legacy":"./base-legacy.js"},"gitHead":"fc2e2023ed5964377cf77d3ef7dfb69fb45249cf","scripts":{"dev":"run-p dev:eslintrc dev:site","lint":"run-s eslint markdownlint","test":"npm run lint && ts-node ./test/index.ts","build":"run-s build:eslintrc build:site","start":"npm run dev","eslint":"eslint ./test --ext .js,.jsx,.ts,.tsx,.vue --ignore-pattern \"bad.*\" .","autotag":"node ./scripts/autoTag.js","dev:site":"parcel site/index.html --out-dir .cache","build:html":"parcel build site/index.html --public-url ./","build:site":"run-s clear:dist build:html","clear:dist":"rimraf ./dist","dev:eslintrc":"nodemon","markdownlint":"markdownlint --config ./.markdownlintrc.json README.md","build:eslintrc":"ts-node scripts/build.ts","test:rulesCoverage":"ts-node ./scripts/rulesCoverage.ts"},"_npmUser":{"name":"ziofat","email":"printlts@gmail.com"},"_npmVersion":"10.9.2","description":"ESLint Config for Tencent","directories":{},"_nodeVersion":"22.14.0","dependencies":{"@eslint/js":"^8.57.0","eslint-plugin-vue":"^9.24.0","typescript-eslint":"^7.18.0","eslint-plugin-chalk":"^1.0.0","eslint-plugin-react":"^7.35.0","@babel/eslint-parser":"^7.14.5","eslint-plugin-import":"^2.31.0","eslint-plugin-prettier":"^3.4.0"},"_hasShrinkwrap":false,"devDependencies":{"husky":"^6.0.0","react":"^17.0.2","cookie":"^0.4.1","eslint":"^8.57.0","rimraf":"^3.0.2","nodemon":"^2.0.7","ts-node":"^10.0.0","doctrine":"^3.0.0","mobi.css":"^3.1.1","prettier":"^2.3.1","react-dom":"^17.0.2","insert-tag":"^0.1.2","typescript":"^4.3.2","xml-escape":"^1.1.0","@types/node":"^18.15.3","npm-run-all":"^4.1.5","@types/react":"^17.0.11","browserslist":"^4.17.6","@types/cookie":"^0.4.0","@types/eslint":"^8.44.2","@types/rimraf":"^3.0.0","react-tooltip":"^4.2.21","parcel-bundler":"^1.12.4","@types/doctrine":"0.0.3","@types/react-dom":"^17.0.7","markdownlint-cli":"^0.27.1","semantic-release":"^17.4.4","@types/eslint__js":"^8.42.3","@types/xml-escape":"^1.1.0","mobi-plugin-color":"^1.0.0","vue-eslint-parser":"^7.6.0","@types/react-tooltip":"^3.11.0"},"peerDependencies":{"eslint":">= 7.28.0 < 10.0.0","@babel/core":"^7.14.6"},"_npmOperationalInternal":{"tmp":"tmp/eslint-config-tencent_1.1.3_1748506320652_0.4694824676965741","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"eslint-config-tencent","version":"1.2.0","description":"ESLint Config for Tencent","main":"index.js","scripts":{"start":"npm run dev","dev":"run-p dev:eslintrc dev:site","dev:eslintrc":"nodemon","dev:site":"parcel site/index.html --out-dir .cache","build":"run-s build:eslintrc build:site","build:eslintrc":"node -r ./config/eslint-env-preload.js ./node_modules/.bin/ts-node scripts/build.ts","build:site":"run-s clear:dist build:html","clear:dist":"rimraf ./dist","build:html":"parcel build site/index.html --public-url ./","test":"npm run lint && ts-node ./test/index.ts","test:eslint-matrix":"ts-node scripts/test-eslint-matrix.ts","test:flat-smoke":"node scripts/test-flat-smoke.js","test:rules":"node -r ./config/eslint-env-preload.js ./node_modules/.bin/ts-node ./test/index.ts","test:rulesCoverage":"ts-node ./scripts/rulesCoverage.ts","lint":"run-s eslint markdownlint","eslint":"node scripts/run-eslint-lint.js","markdownlint":"markdownlint --config ./.markdownlintrc.json README.md","autotag":"node ./scripts/autoTag.js"},"repository":{"type":"git","url":"https://git.woa.com/standards/javascript.git"},"keywords":["eslint","eslintrc","eslintconfig","config","tencent","javascript","styleguide","react","vue","typescript"],"author":"","contributors":[{"name":"xcatliu","email":"xcaliu@tencent.com"},{"name":"ziofatli","email":"ziofatli@tencent.com"}],"license":"MIT","homepage":"https://git.woa.com/standards/javascript","exports":{".":"./index.js","./base":"./base.js","./base-legacy":"./base-legacy.js","./ts":"./ts.js","./ts-legacy":"./ts-legacy.js","./import":"./import.js","./react":"./react.js","./prettier":"./prettier.js","./flat":"./flat/index.js"},"dependencies":{"@babel/eslint-parser":"^7.14.5","@eslint/js":"^8.57.0","@stylistic/eslint-plugin":"^3.1.0","eslint-plugin-chalk":"^1.0.0","eslint-plugin-import":"^2.31.0","eslint-plugin-prettier":"^3.4.0","eslint-plugin-react":"^7.35.0","eslint-plugin-vue":"^9.24.0","typescript-eslint":"^8.61.0"},"peerDependencies":{"@babel/core":"^7.14.6","eslint":"^8.57.0 || ^9.0.0 || ^10.0.0"},"devDependencies":{"@types/cookie":"^0.4.0","@types/doctrine":"0.0.3","@types/eslint":"^8.44.2","@types/eslint__js":"^8.42.3","@types/node":"^18.15.3","@types/react":"^17.0.11","@types/react-dom":"^17.0.7","@types/react-tooltip":"^3.11.0","@types/rimraf":"^3.0.0","@types/xml-escape":"^1.1.0","browserslist":"^4.17.6","cookie":"^0.4.1","doctrine":"^3.0.0","eslint":"^8.57.1","husky":"^6.0.0","insert-tag":"^0.1.2","markdownlint-cli":"^0.27.1","mobi-plugin-color":"^1.0.0","mobi.css":"^3.1.1","nodemon":"^2.0.7","npm-run-all":"^4.1.5","parcel-bundler":"^1.12.4","prettier":"^2.3.1","react":"^17.0.2","react-dom":"^17.0.2","react-tooltip":"^4.2.21","rimraf":"^3.0.2","semantic-release":"^17.4.4","ts-node":"^10.0.0","typescript":"^5.5.0","vue-eslint-parser":"^7.6.0","xml-escape":"^1.1.0"},"_id":"eslint-config-tencent@1.2.0","gitHead":"7708ca13d06473c432b550246f5a7042940173c0","_nodeVersion":"22.22.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-cWyONap6dqhXeKbW3+qxxO/44DwbyOhpROZrgt6j2IrysJzYGAWXzLr94mqv+ePZV/Zziy2vrlyqt/zTkWfclQ==","shasum":"cd45d28ace5fa02a8556807e5894d295bc74209f","tarball":"https://registry.npmjs.org/eslint-config-tencent/-/eslint-config-tencent-1.2.0.tgz","fileCount":20,"unpackedSize":198705,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDerEodmZakK61TK3NmPSK+yVE+/kz+45FJ5rhxGBJmvwIgIGlPcOR3n5o2nrP09KLME1McobxBm4K4yIU7YaLB1nc="}]},"_npmUser":{"name":"ziofat","email":"printlts@gmail.com"},"directories":{},"maintainers":[{"name":"xcatliu","email":"xcatliu@gmail.com"},{"name":"xuqingkuang","email":"x@kxq.io"},{"name":"ziofat","email":"printlts@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/eslint-config-tencent_1.2.0_1782898040830_0.6038375774621942"},"_hasShrinkwrap":false}},"time":{"created":"2019-09-04T01:43:59.407Z","modified":"2026-07-01T09:27:21.090Z","0.0.1-beta.1":"2019-09-04T01:43:59.544Z","1.0.0":"2020-09-07T09:06:26.536Z","1.0.1":"2021-06-18T09:54:41.859Z","1.0.2":"2021-06-28T04:01:06.787Z","1.0.3":"2022-02-17T08:28:04.589Z","1.0.4":"2022-03-30T03:15:45.705Z","1.1.0":"2024-10-21T13:35:11.959Z","1.1.1":"2024-10-22T06:23:38.500Z","1.1.2":"2024-12-19T06:14:46.694Z","1.1.3":"2025-05-29T08:12:00.936Z","1.2.0":"2026-07-01T09:27:20.973Z"},"license":"MIT","keywords":["eslint","eslintrc","eslintconfig","config","tencent","javascript","styleguide","react","vue","typescript"],"description":"ESLint Config for Tencent","contributors":[{"name":"xcatliu","email":"xcaliu@tencent.com"},{"name":"ziofatli","email":"ziofatli@tencent.com"}],"maintainers":[{"name":"xcatliu","email":"xcatliu@gmail.com"},{"name":"xuqingkuang","email":"x@kxq.io"},{"name":"ziofat","email":"printlts@gmail.com"}],"readme":"# JavaScript 编码规范\n\n[TOC]\n\n## 前言\n\n为前端开发提供良好的基础编码风格修行指南。\n\n基于 [Airbnb](https://github.com/airbnb/javascript#table-of-contents) 编码规范。所有规范分为三个等级：**必须**、**推荐**、**可选**。\n\n**必须（Mandatory）** 级别要求员工必须严格按照规范的编码格式编写，否则会在代码扫描和自动化构建中报错。对应 [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) 中的 `MUST`, `MUST NOT` 和 `REQUIRED` 级别。\n\n**推荐（Preferable）** 级别希望员工尽量按照规范编写，但如有特殊情况，可以不采用。对应 [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) 中的 `SHOULD`, `SHOULD NOT` 级别。\n\n**可选（Optional）** 级别并不对员工编码提出要求，一般是JavaScript常识以及ES6、ES7的新语法，但仍希望员工按参考规范编写。委员会将定期review编码规范，不断提高规范等级要求。对应 [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt) 中的 `MAY` 级别。\n\n本文档中的代码为示例代码，出于演示目的，不一定完全符合本文档所规定的所有规则要求。\n\n本文档中的示例代码中会有 Good 或 Best 的提示，表示这是遵守代码规范的一种写法。\n需要说明的是，虽然 Good 写法符合这条规范，但不代表这是满足规范的唯一方式。\n\n未尽事宜，应当首先以同一文件中的其他类似风格为准，若该文件中没有类似结构，则以项目风格为准。一致性是最重要的。\n\n### License\n\n基于 MIT 协议开源。\n\n查看 [Notice](./NOTICE) 文件了解注明和鸣谢信息。\n\n## 0. 相关工具\n\n### eslint-config-tencent 规则包\n\n安装:\n\njavascript\n\n```shell\ntnpm install eslint @tencent/eslint-config-tencent --save-dev\n```\n\n#### ESLint 传统配置 Legacy Config\n\n_.eslintrc.js:_\n\n```javascript\nmodule.exports = {\n  extends: ['@tencent/eslint-config-tencent'],\n}\n```\n\ntypescript 还需要安装依赖\n\n```shell\ntnpm install @typescript-eslint/eslint-plugin @typescript-eslint/parser --save-dev\n```\n\n_.eslintrc.js:_\n\n```javascript\nmodule.exports = {\n  extends: ['@tencent/eslint-config-tencent', '@tencent/eslint-config-tencent/ts'],\n}\n```\n\n使用 prettier 的用户需要安装对应的依赖\n\n```shell\ntnpm install prettier eslint-plugin-prettier --save-dev\n```\n\n_.eslintrc.js:_\n\n```javascript\nmodule.exports = {\n  extends: ['@tencent/eslint-config-tencent', '@tencent/eslint-config-tencent/ts', '@tencent/eslint-config-tencent/prettier'],\n}\n```\n\n**注意：使用 prettier 规则之后，会自动禁用掉与之相冲突的格式相关的规则。由于prettier与ESLint存在冲突，开源扫描仍以ESLint扫描结果为准。**\n\n#### ESLint 新版扁平配置 Flat Config\n\n推荐使用 cjs 作为配置文件后缀，可兼容 type: module 和 type: commonjs 的项目。\n\neslint.config.cjs:\n\n```js\nconst tencentEslintConfig = require('@tencent/eslint-config-tencent/flat');\nmodule.exports = tencentEslintConfig({});\n```\n\n使用 TypeScript 的项目需要传入 `tsconfig.json` 所在的目录位置,\n\neslint.config.cjs:\n\n```js\nconst tencentEslintConfig = require('@tencent/eslint-config-tencent/flat');\nmodule.exports = tencentEslintConfig({\n  tsconfigRootDir: __dirname,\n});\n```\n\n### Orange-ci 插件\n\n增量检查\n\n```yaml\nmaster:\n  merge_request:\n    - stages:\n      - name: make changelist\n        type: git:changeList\n        options:\n          changed: changed.txt\n      - name: git diff eslint-config-tencent\n        image: csighub.tencentyun.com/standards/eslint-config-tencent:latest\n        settings:\n          change_file: changed.txt\n```\n\n全量检查\n\n```yaml\nmaster:\n  merge_request:\n    - stages:\n      - name: git eslint-config-tencent\n        image: csighub.tencentyun.com/standards/eslint-config-tencent:latest\n```\n\n### 工蜂CI 插件\n\n全量检查\n\n```yaml\nmr:\n  branches:\n    include:\n      - master\nstages:\n  - stage:\n    - job:\n        name: eslint\n        steps:\n        - taskType: dockerRun@latest\n          displayName: dockerRun\n          inputs:\n            image: csighub.tencentyun.com/standards/eslint-config-tencent:latest\n            cmd: \"\"\n```\n\n## 1. 类型\n\n- [1.1](#types--primitives) <a id=\"types--primitives\"></a> **【可选】 基本类型**: 当你访问一个基本类型时，直接操作它的值。\n\n  - `string`\n  - `number`\n  - `boolean`\n  - `null`\n  - `undefined`\n  - `symbol`\n\n  ```javascript\n  const foo = 1;\n  let bar = foo;\n\n  bar = 9;\n\n  console.log(foo, bar); // => 1, 9\n  ```\n\n  - 符号（Symbols）不能完全的被 [polyfill](https://en.wikipedia.org/wiki/Polyfill_(programming))，因此在不能原生支持symbol类型的浏览器或环境中，不应该使用symbol类型。\n\n- [1.2](#types--complex) <a id=\"types--complex\"></a>  **【可选】 复杂类型**: 当你访问一个复杂类型时，直接操作其值的引用。\n\n  - `object`\n  - `array`\n  - `function`\n\n  ```javascript\n  const foo = [1, 2];\n  const bar = foo;\n\n  bar[0] = 9;\n\n  console.log(foo[0], bar[0]); // => 9, 9\n  ```\n\n## 2. 引用\n\n- [2.1](#references--prefer-const) <a id=\"references--prefer-const\"></a> **【必须】** 使用 `const` 定义你的所有引用；避免使用 `var`。 eslint: [`prefer-const`](https://eslint.org/docs/rules/prefer-const.html), [`no-const-assign`](https://eslint.org/docs/rules/no-const-assign.html)\n\n  > 原因? 这样能够确保你不能重新赋值你的引用，否则可能导致错误或者产生难以理解的代码。\n\n  ```javascript\n  // bad\n  var a = 1;\n  var b = 2;\n\n  // good\n  const a = 1;\n  const b = 2;\n  ```\n\n- [2.2](#references--disallow-var) <a id=\"references--disallow-var\"></a> **【必须】** 如果你必须重新赋值你的引用， 使用 `let` 代替 `var`。 eslint: [`no-var`](https://eslint.org/docs/rules/no-var.html)\n\n  > 原因? `let` 是块级作用域，而不像 `var` 是函数作用域。\n\n  ```javascript\n  // bad\n  var count = 1;\n  if (true) {\n    count += 1;\n  }\n\n  // good, use the let.\n  let count = 1;\n  if (true) {\n    count += 1;\n  }\n  ```\n\n- [2.3](#references--block-scope) <a id=\"references--block-scope\"></a> **【可选】** 注意，let 和 const 都是块级作用域。\n\n  ```javascript\n  // const 和 let 只存在于他们定义的块级作用域中。\n  {\n    let a = 1;\n    const b = 1;\n  }\n  console.log(a); // ReferenceError\n  console.log(b); // ReferenceError\n  ```\n\n## 3. 对象\n\n- [3.1](#objects--no-new) <a id=\"objects--no-new\"></a> **【必须】** 使用字面量语法创建对象。 eslint: [`no-new-object`](https://eslint.org/docs/rules/no-new-object.html)\n\n  ```javascript\n  // bad\n  const item = new Object();\n\n  // good\n  const item = {};\n  ```\n\n- [3.2](#es6-computed-properties) <a id=\"es6-computed-properties\"></a> **【推荐】** 在创建具有动态属性名称的对象时使用计算属性名。\n\n  > 原因? 它允许你在一个地方定义对象的所有属性。\n\n  ```javascript\n  function getKey(k) {\n    return `a key named ${k}`;\n  }\n\n  // bad\n  const obj = {\n    id: 5,\n    name: 'San Francisco',\n  };\n  obj[getKey('enabled')] = true;\n\n  // good\n  const obj = {\n    id: 5,\n    name: 'San Francisco',\n    [getKey('enabled')]: true,\n  };\n  ```\n\n- [3.3](#es6-object-shorthand) <a id=\"es6-object-shorthand\"></a> **【推荐】** 用对象方法简写。 eslint: [`object-shorthand`](https://eslint.org/docs/rules/object-shorthand.html)\n\n  ```javascript\n  // bad\n  const value = 1;\n  const atom = {\n    value: value,\n    addValue: function (newValue) {\n      return atom.value + newValue;\n    },\n  };\n\n  // good\n  const value = 1;\n  const atom = {\n    value,\n    addValue(newValue) {\n      return atom.value + newValue;\n    },\n  };\n  ```\n\n- [3.4](#es6-object-concise) <a id=\"es6-object-concise\"></a> **【推荐】** 用属性值简写。 eslint: [`object-shorthand`](https://eslint.org/docs/rules/object-shorthand.html)\n\n  > 原因? 它更加简洁并更具描述性。\n\n  ```javascript\n  const lukeSkywalker = 'Luke Skywalker';\n\n  // bad\n  const obj = {\n    lukeSkywalker: lukeSkywalker,\n  };\n\n  // good\n  const obj = {\n    lukeSkywalker,\n  };\n  ```\n\n- [3.5](#objects--grouped-shorthand) <a id=\"objects--grouped-shorthand\"></a> **【推荐】** 声明对象时，将简写的属性放在前面。\n\n  > 原因? 这样更容易的判断哪些属性使用的简写。\n\n  ```javascript\n  const anakinSkywalker = 'Anakin Skywalker';\n  const lukeSkywalker = 'Luke Skywalker';\n\n  // bad\n  const obj = {\n    episodeOne: 1,\n    twoJediWalkIntoACantina: 2,\n    lukeSkywalker,\n    episodeThree: 3,\n    mayTheFourth: 4,\n    anakinSkywalker,\n  };\n\n  // good\n  const obj = {\n    lukeSkywalker,\n    anakinSkywalker,\n    episodeOne: 1,\n    twoJediWalkIntoACantina: 2,\n    episodeThree: 3,\n    mayTheFourth: 4,\n  };\n  ```\n\n- [3.6](#objects--quoted-props) <a id=\"objects--quoted-props\"></a> **【必须】** 只使用引号标注无效标识符的属性。 eslint: [`quote-props`](https://eslint.org/docs/rules/quote-props.html)\n\n  > 原因? 一般来说，我们认为这样更容易阅读。 它能更好地适配语法高亮显示功能，并且更容易通过许多 JS 引擎进行优化。\n\n  ```javascript\n  // bad\n  const bad = {\n    'foo': 3,\n    'bar': 4,\n    'data-blah': 5,\n  };\n\n  // good\n  const good = {\n    foo: 3,\n    bar: 4,\n    'data-blah': 5,\n  };\n  ```\n\n- [3.7](#objects--prototype-builtins) <a id=\"objects--prototype-builtins\"></a> **【推荐】** 不能直接调用 `Object.prototype` 的方法，如： `hasOwnProperty` 、 `propertyIsEnumerable` 和 `isPrototypeOf`。 eslint: [`no-prototype-builtins`](https://eslint.org/docs/rules/no-prototype-builtins.html)\n\n  > 原因? 这些方法可能被有问题的对象上的属性覆盖 - 如 `{ hasOwnProperty: false }` - 或者，对象是一个空对象 (`Object.create(null)`)。\n\n  ```javascript\n  // bad\n  console.log(object.hasOwnProperty(key));\n\n  // good\n  console.log(Object.prototype.hasOwnProperty.call(object, key));\n\n  // best\n  const has = Object.prototype.hasOwnProperty; // 在模块范围内的缓存中查找一次\n  console.log(has.call(object, key));\n\n  /* or */\n  import has from 'has'; // https://www.npmjs.com/package/has\n  console.log(has(object, key));\n  ```\n\n- [3.8](#objects--rest-spread) <a id=\"objects--rest-spread\"></a> **【推荐】** 使用对象扩展操作符（spread operator）浅拷贝对象，而不是用 [`Object.assign`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) 方法。 使用对象的剩余操作符（rest operator）来获得一个新对象，该对象省略了某些属性。 eslint: [`prefer-object-spread`](https://eslint.org/docs/rules/prefer-object-spread)\n\n  ```javascript\n  // very bad\n  const original = { a: 1, b: 2 };\n  const copy = Object.assign(original, { c: 3 }); // 变异的 `original` ಠ_ಠ\n  delete copy.a; // 这....\n\n  // bad\n  const original = { a: 1, b: 2 };\n  const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }\n\n  // good\n  const original = { a: 1, b: 2 };\n  const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 }\n\n  const { a, ...noA } = copy; // noA => { b: 2, c: 3 }\n  ```\n\n## 4. 数组\n\n- [4.1](#arrays--literals) <a id=\"arrays--literals\"></a> **【必须】** 使用字面量语法创建数组。 eslint: [`no-array-constructor`](https://eslint.org/docs/rules/no-array-constructor.html)\n\n  ```javascript\n  // bad\n  const items = new Array();\n\n  // good\n  const items = [];\n  ```\n\n- [4.2](#arrays--push) <a id=\"arrays--push\"></a> **【必须】** 使用 [Array#push](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/push) 代替直接赋值来给数组添加项。\n\n  ```javascript\n  const someStack = [];\n\n  // bad\n  someStack[someStack.length] = 'abracadabra';\n\n  // good\n  someStack.push('abracadabra');\n  ```\n\n- [4.3](#es6-array-spreads) <a id=\"es6-array-spreads\"></a> **【必须】** 使用数组展开符 `...` 来拷贝数组。\n\n  ```javascript\n  // bad\n  const len = items.length;\n  const itemsCopy = [];\n  let i;\n\n  for (i = 0; i < len; i += 1) {\n    itemsCopy[i] = items[i];\n  }\n\n  // good\n  const itemsCopy = [...items];\n  ```\n\n- [4.4](#arrays--from) <a id=\"arrays--from\"></a> **【推荐】** 使用展开符 `...` 代替 [`Array.from`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from)，将一个可迭代对象转换成一个数组。\n\n  ```javascript\n  const foo = document.querySelectorAll('.foo');\n\n  // good\n  const nodes = Array.from(foo);\n\n  // best\n  const nodes = [...foo];\n  ```\n\n- [4.5](#arrays--mapping) <a id=\"arrays--mapping\"></a> **【必须】** 使用 [Array.from](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from) 将一个类数组（array-like）对象转换成一个数组。\n\n  ```javascript\n  const arrLike = { 0: 'foo', 1: 'bar', 2: 'baz', length: 3 };\n\n  // bad\n  const arr = Array.prototype.slice.call(arrLike);\n\n  // good\n  const arr = Array.from(arrLike);\n  ```\n\n- [4.6](#arrays--mapping) <a id=\"arrays--mapping\"></a> **【必须】** 使用 [Array.from](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from) 代替展开符 `...` 映射迭代器，因为它避免了创建一个中间数组。\n\n  ```javascript\n  // bad\n  const baz = [...foo].map(bar);\n\n  // good\n  const baz = Array.from(foo, bar);\n  ```\n\n- [4.7](#arrays--callback-return) <a id=\"arrays--callback-return\"></a> **【推荐】** 在数组回调函数中使用 return 语句。 如果函数体由单个语句的返回表达式组成，并且无副作用，那么可以省略返回值， 具体查看 [8.2](#arrows--implicit-return) <a id=\"arrows--implicit-return\"></a>。 eslint: [`array-callback-return`](https://eslint.org/docs/rules/array-callback-return)\n\n  ```javascript\n  // good\n  [1, 2, 3].map((x) => {\n    const y = x + 1;\n    return x * y;\n  });\n\n  // good\n  [1, 2, 3].map(x => x + 1);\n\n  // bad - 没有返回值，意味着在第一次迭代后 `acc` 没有被定义\n  [[0, 1], [2, 3], [4, 5]].reduce((acc, item, index) => {\n    const flatten = acc.concat(item);\n    acc[index] = flatten;\n  });\n\n  // good\n  [[0, 1], [2, 3], [4, 5]].reduce((acc, item, index) => {\n    const flatten = acc.concat(item);\n    acc[index] = flatten;\n    return flatten;\n  }, []);\n\n  // bad\n  inbox.filter((msg) => {\n    const { subject, author } = msg;\n    if (subject === 'Mockingbird') {\n      return author === 'Harper Lee';\n    } else {\n      return false;\n    }\n  });\n\n  // good\n  inbox.filter((msg) => {\n    const { subject, author } = msg;\n    if (subject === 'Mockingbird') {\n      return author === 'Harper Lee';\n    }\n\n    return false;\n  });\n  ```\n\n- [4.8](#arrays--bracket-newline) <a id=\"arrays--bracket-newline\"></a> **【推荐】** 如果数组有多行，则在数组开始括号 `[` 的时候换行，然后在数组结束括号 `]`  的时候换行。 eslint: [`array-bracket-newline`](https://eslint.org/docs/rules/array-bracket-newline)\n\n  ```javascript\n  // bad\n  const arr = [\n    [0, 1], [2, 3], [4, 5],\n  ];\n\n  const objectInArray = [{\n    id: 1,\n  }, {\n    id: 2,\n  }];\n\n  const numberInArray = [\n    1, 2,\n  ];\n\n  // good\n  const arr = [[0, 1], [2, 3], [4, 5]];\n\n  const objectInArray = [\n    {\n      id: 1,\n    },\n    {\n      id: 2,\n    },\n  ];\n\n  const numberInArray = [\n    1,\n    2,\n  ];\n  ```\n\n## 5. 解构\n\n- [5.1](#destructuring--object) <a id=\"destructuring--object\"></a> **【推荐】** 在访问和使用对象的多个属性时使用对象解构。 eslint: [`prefer-destructuring`](https://eslint.org/docs/rules/prefer-destructuring)\n\n  > 原因? 解构可以避免为这些属性创建临时引用。\n\n  ```javascript\n  // bad\n  function getFullName(user) {\n    const firstName = user.firstName;\n    const lastName = user.lastName;\n\n    return `${firstName} ${lastName}`;\n  }\n\n  // good\n  function getFullName(user) {\n    const { firstName, lastName } = user;\n    return `${firstName} ${lastName}`;\n  }\n\n  // best\n  function getFullName({ firstName, lastName }) {\n    return `${firstName} ${lastName}`;\n  }\n  ```\n\n- [5.2](#destructuring--array) <a id=\"destructuring--array\"></a> **【推荐】** 使用数组解构。 eslint: [`prefer-destructuring`](https://eslint.org/docs/rules/prefer-destructuring)\n\n  ```javascript\n  const arr = [1, 2, 3, 4];\n\n  // bad\n  const first = arr[0];\n  const second = arr[1];\n\n  // good\n  const [first, second] = arr;\n  ```\n\n- [5.3](#destructuring--object-over-array) <a id=\"destructuring--object-over-array\"></a> **【必须】** 在有多个返回值时, 使用对象解构，而不是数组解构。\n\n  > 原因? 你可以随时添加新的属性或者改变属性的顺序，而不用修改调用方。\n\n  ```javascript\n  // bad\n  function processInput(input) {\n    // 处理代码...\n    return [left, right, top, bottom];\n  }\n\n  // 调用者需要考虑返回数据的顺序。\n  const [left, __, top] = processInput(input);\n\n  // good\n  function processInput(input) {\n    // 处理代码...\n    return { left, right, top, bottom };\n  }\n\n  // 调用者只选择他们需要的数据。\n  const { left, top } = processInput(input);\n  ```\n\n## 6. 字符\n\n- [6.1](#strings--quotes) <a id=\"strings--quotes\"></a> **【推荐】** 使用单引号 `''` 定义字符串。 eslint: [`quotes`](https://eslint.org/docs/rules/quotes.html)\n\n  ```javascript\n  // bad\n  const name = \"Capt. Janeway\";\n\n  // bad - 模板文字应该包含插值或换行。\n  const name = `Capt. Janeway`;\n\n  // good\n  const name = 'Capt. Janeway';\n  ```\n\n- [6.2](#strings--line-length) <a id=\"strings--line-length\"></a> **【必须】** 不应该用字符串跨行连接符的格式来跨行编写,这样会使当前行长度超过100个字符。\n\n  > 原因? 断开的字符串维护起来很痛苦，并且会提高索引难度。\n\n  ```javascript\n  // bad\n  const errorMessage = 'This is a super long error that was thrown because \\\n  of Batman. When you stop to think about how Batman had anything to do \\\n  with this, you would get nowhere \\\n  fast.';\n\n  // bad\n  const errorMessage = 'This is a super long error that was thrown because ' +\n    'of Batman. When you stop to think about how Batman had anything to do ' +\n    'with this, you would get nowhere fast.';\n\n  // good\n  const errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.';\n  ```\n\n- [6.3](#es6-template-literals) <a id=\"es6-template-literals\"></a> **【必须】** 构建字符串时，使用字符串模板代替字符串拼接。 eslint: [`prefer-template`](https://eslint.org/docs/rules/prefer-template.html) [`template-curly-spacing`](https://eslint.org/docs/rules/template-curly-spacing)\n\n  > 原因? 字符串模板为您提供了一种可读的、简洁的语法，具有正确的换行和字符串插值特性。\n\n  ```javascript\n  // bad\n  function sayHi(name) {\n    return 'How are you, ' + name + '?';\n  }\n\n  // bad\n  function sayHi(name) {\n    return ['How are you, ', name, '?'].join();\n  }\n\n  // bad\n  function sayHi(name) {\n    return `How are you, ${ name }?`;\n  }\n\n  // good\n  function sayHi(name) {\n    return `How are you, ${name}?`;\n  }\n  ```\n\n- [6.4](#strings--eval) <a id=\"strings--eval\"></a> **【必须】** 永远不要使用 `eval()` 执行放在字符串中的代码，它导致了太多的漏洞。 eslint: [`no-eval`](https://eslint.org/docs/rules/no-eval)\n\n- [6.5](#strings--escaping) <a id=\"strings--escaping\"></a> **【必须】** 不要在字符串中转义不必要的字符。 eslint: [`no-useless-escape`](https://eslint.org/docs/rules/no-useless-escape)\n\n  > 原因? 反斜杠损害了可读性，因此只有在必要的时候才可以出现。\n\n  ```javascript\n  // bad\n  const foo = '\\'this\\' \\i\\s \\\"quoted\\\"';\n\n  // good\n  const foo = '\\'this\\' is \"quoted\"';\n  const foo = `my name is '${name}'`;\n  ```\n\n## 7. 函数\n\n- [7.1](#functions--declarations) <a id=\"functions--declarations\"></a> **【可选】** 使用命名的函数表达式代替函数声明。 eslint: [`func-style`](https://eslint.org/docs/rules/func-style)\n\n  > 原因? 函数声明时作用域被提前了，这意味着在一个文件里函数很容易（太容易了）在其定义之前被引用。这样伤害了代码可读性和可维护性。如果你发现一个函数又大又复杂，并且它干扰了对这个文件其他部分的理解，那么是时候把这个函数单独抽成一个模块了！别忘了给表达式显式的命名，不用管这个名字是不是由一个确定的变量推断出来的（这在现代浏览器和类似babel编译器中很常见）。这消除了由匿名函数在错误调用栈产生的所有假设。 * ([Discussion](https://github.com/airbnb/javascript/issues/794))\n\n  ```javascript\n  // bad\n  function foo() {\n    // ...\n  }\n\n  // also good *\n  const foo = function () {\n    // ...\n  };\n\n  // good\n  const short = function longUniqueMoreDescriptiveLexicalFoo() {\n    // ...\n  };\n  ```\n\n- [7.2](#functions--iife) <a id=\"functions--iife\"></a> **【必须】** 把立即执行函数包裹在圆括号里。 eslint: [`wrap-iife`](https://eslint.org/docs/rules/wrap-iife.html)\n\n  > 原因? 立即调用的函数表达式是个独立的单元 - 将它和它的调用括号还有入参包装在一起可以非常清晰的表明这一点。请注意，在一个到处都是模块的世界中，您几乎用不到 IIFE。\n\n  ```javascript\n  // immediately-invoked function expression (IIFE) 立即调用的函数表达式\n  (function () {\n    console.log('Welcome to the Internet. Please follow me.');\n  }());\n  ```\n\n- [7.3](#functions--in-blocks) <a id=\"functions--in-blocks\"></a> **【必须】** 切记不要在非功能块中声明函数 (`if`, `while`, 等)。 请将函数赋值给变量。 浏览器允许你这样做， 但是不同浏览器会有不同的行为， 这并不是什么好事。 eslint: [`no-loop-func`](https://eslint.org/docs/rules/no-loop-func.html)\n\n- [7.4](#functions--note-on-blocks) <a id=\"functions--note-on-blocks\"></a> **【必须】** ECMA-262 将 `block` 定义为语句列表。 而函数声明并不是语句。\n\n  ```javascript\n  // bad\n  if (currentUser) {\n    function test() {\n      console.log('Nope.');\n    }\n  }\n\n  // good\n  let test;\n  if (currentUser) {\n    test = () => {\n      console.log('Yup.');\n    };\n  }\n  ```\n\n- [7.5](#functions--arguments-shadow) <a id=\"functions--arguments-shadow\"></a> **【必须】** 永远不要给一个参数命名为 `arguments`。 这将会覆盖函数默认的 `arguments` 对象。 eslint: [`no-shadow-restricted-names`](https://eslint.org/docs/rules/no-shadow-restricted-names)\n\n  ```javascript\n  // bad\n  function foo(name, options, arguments) {\n    // ...\n  }\n\n  // good\n  function foo(name, options, args) {\n    // ...\n  }\n  ```\n\n- [7.6](#es6-rest) <a id=\"es6-rest\"></a> **【推荐】** 使用 rest 语法 `...` 代替 `arguments`。 eslint: [`prefer-rest-params`](https://eslint.org/docs/rules/prefer-rest-params)\n\n  > 原因? `...` 明确了你想要拉取什么参数。 而且, rest 参数是一个真正的数组，而不仅仅是类数组的 `arguments` 。\n\n  ```javascript\n  // bad\n  function concatenateAll() {\n    const args = Array.prototype.slice.call(arguments);\n    return args.join('');\n  }\n\n  // good\n  function concatenateAll(...args) {\n    return args.join('');\n  }\n  ```\n\n- [7.7](#es6-default-parameters) <a id=\"es6-default-parameters\"></a> **【推荐】** 使用默认的参数语法，而不是改变函数参数。\n\n  ```javascript\n  // really bad\n  function handleThings(opts) {\n    // 不！我们不应该修改参数。\n    // 更加错误的是： 如果 opts 是一个 \"非正值\"（falsy）它将被设置成一个对象\n    // 这或许正是你想要的，但它可能会导致一些难以察觉的错误。\n    opts = opts || {};\n    // ...\n  }\n\n  // still bad\n  function handleThings(opts) {\n    if (opts === void 0) {\n      opts = {};\n    }\n    // ...\n  }\n\n  // good\n  function handleThings(opts = {}) {\n    // ...\n  }\n  ```\n\n- [7.8](#functions--default-side-effects) <a id=\"functions--default-side-effects\"></a> **【必须】** 使用默认参数时避免副作用。\n\n  > 原因? 他们很容易混淆。\n\n  ```javascript\n  var b = 1;\n  // bad\n  function count(a = b++) {\n    console.log(a);\n  }\n  count();  // 1\n  count();  // 2\n  count(3); // 3\n  count();  // 3\n  ```\n\n- [7.9](#functions--defaults-last) <a id=\"functions--defaults-last\"></a> **【推荐】** 总是把默认参数放在最后。 eslint: [`default-param-last`](https://eslint.org/docs/rules/default-param-last)\n\n  ```javascript\n  // bad\n  function handleThings(opts = {}, name) {\n    // ...\n  }\n\n  // good\n  function handleThings(name, opts = {}) {\n    // ...\n  }\n  ```\n\n- [7.10](#functions--constructor) <a id=\"functions--constructor\"></a> **【推荐】** 永远不要使用函数构造器来创建一个新函数。 eslint: [`no-new-func`](https://eslint.org/docs/rules/no-new-func)\n\n  > 原因? 以这种方式创建一个函数跟 `eval()` 差不多，将会导致漏洞。\n\n  ```javascript\n  // bad\n  var add = new Function('a', 'b', 'return a + b');\n\n  // still bad\n  var subtract = Function('a', 'b', 'return a - b');\n  ```\n\n- [7.11](#functions--signature-spacing) <a id=\"functions--signature-spacing\"></a> **【必须】** 函数声明语句中需要空格。 eslint: [`space-before-function-paren`](https://eslint.org/docs/rules/space-before-function-paren) [`space-before-blocks`](https://eslint.org/docs/rules/space-before-blocks)\n\n  > 原因? 一致性很好，在删除或添加名称时不需要添加或删除空格。\n\n  ```javascript\n  // bad\n  const f = function(){};\n  const g = function (){};\n  const h = function() {};\n\n  // good\n  const x = function () {};\n  const y = function a() {};\n  ```\n\n- [7.12](#functions--mutate-params) <a id=\"functions--mutate-params\"></a> **【推荐】** 不要改变入参。 eslint: [`no-param-reassign`](https://eslint.org/docs/rules/no-param-reassign.html)\n\n  > 原因? 操作入参对象会导致原始调用位置出现意想不到的副作用。\n\n  ```javascript\n  // bad\n  function f1(obj) {\n    obj.key = 1;\n  }\n\n  // good\n  function f2(obj) {\n    const key = Object.prototype.hasOwnProperty.call(obj, 'key') ? obj.key : 1;\n  }\n  ```\n\n- [7.13](#functions--reassign-params) <a id=\"functions--reassign-params\"></a> **【推荐】** 不要对入参重新赋值，也不要给入参的属性赋值。部分要求修改入参的常用库（如 Koa、Vuex）可以豁免。 eslint: [`no-param-reassign`](https://eslint.org/docs/rules/no-param-reassign.html)\n\n  > 原因? 重新赋值参数会导致意外的行为，尤其是在访问 `arguments` 对象的时候。 它还可能导致性能优化问题，尤其是在 V8 中。\n\n  ```javascript\n  // bad\n  function f1(a) {\n    a = 1;\n    // ...\n  }\n\n  function f2(a) {\n    if (!a) { a = 1; }\n    // ...\n  }\n\n  // good\n  function f3(a) {\n    const b = a || 1;\n    // ...\n  }\n\n  function f4(a = 1) {\n    // ...\n  }\n  ```\n\n- [7.14](#functions--spread-vs-apply) <a id=\"functions--spread-vs-apply\"></a> **【推荐】** 优先使用扩展运算符 `...` 来调用可变参数函数。 eslint: [`prefer-spread`](https://eslint.org/docs/rules/prefer-spread)\n\n  > 原因? 它更加清晰，你不需要提供上下文，并且能比用 `apply` 来执行可变参数的 `new` 操作更容易些。\n\n  ```javascript\n  // bad\n  const x = [1, 2, 3, 4, 5];\n  console.log.apply(console, x);\n\n  // good\n  const x = [1, 2, 3, 4, 5];\n  console.log(...x);\n\n  // bad\n  new (Function.prototype.bind.apply(Date, [null, 2016, 8, 5]));\n\n  // good\n  new Date(...[2016, 8, 5]);\n  ```\n\n- [7.15](#functions--signature-invocation-indentation) <a id=\"functions--signature-invocation-indentation\"></a> **【推荐】** 调用或者书写一个包含多个参数的函数应该像这个指南里的其他多行代码写法一样： 每行值包含一个参数，并且最后一行也要以逗号结尾。eslint: [`function-paren-newline`](https://eslint.org/docs/rules/function-paren-newline)\n\n  ```javascript\n  // bad\n  function foo(bar,\n                baz,\n                quux) {\n    // ...\n  }\n\n  // good\n  function foo(\n    bar,\n    baz,\n    quux,\n  ) {\n    // ...\n  }\n\n  // bad\n  console.log(foo,\n    bar,\n    baz);\n\n  // good\n  console.log(\n    foo,\n    bar,\n    baz,\n  );\n  ```\n\n## 8. 箭头函数\n\n- [8.1](#arrows--use-them) <a id=\"arrows--use-them\"></a> **【推荐】** 当你必须使用匿名函数时 (当传递内联函数时)， 使用箭头函数。 eslint: [`prefer-arrow-callback`](https://eslint.org/docs/rules/prefer-arrow-callback.html), [`arrow-spacing`](https://eslint.org/docs/rules/arrow-spacing.html)\n\n  > 原因? 它创建了一个在 `this` 上下文中执行的函数版本，它通常是你想要的，并且是一个更简洁的语法。\n\n  > 什么时候不适用? 如果你有一个相当复杂的函数，你可能会把这些逻辑转移到它自己的命名函数表达式里。\n\n  ```javascript\n  // bad\n  [1, 2, 3].map(function (x) {\n    const y = x + 1;\n    return x * y;\n  });\n\n  // good\n  [1, 2, 3].map((x) => {\n    const y = x + 1;\n    return x * y;\n  });\n  ```\n\n- [8.2](#arrows--implicit-return) <a id=\"arrows--implicit-return\"></a> **【推荐】** 如果函数体由一个没有副作用的 [表达式](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Expressions) 语句组成，删除大括号和 `return`。否则，保留括号并继续使用 `return` 语句。 eslint: [`arrow-parens`](https://eslint.org/docs/rules/arrow-parens.html), [`arrow-body-style`](https://eslint.org/docs/rules/arrow-body-style.html)\n\n  > 原因? 语法糖。 多个函数被链接在一起时，提高可读性。\n\n  ```javascript\n  // bad\n  [1, 2, 3].map(number => {\n    const nextNumber = number + 1;\n    `A string containing the ${nextNumber}.`;\n  });\n\n  // good\n  [1, 2, 3].map(number => `A string containing the ${number + 1}.`);\n\n  // good\n  [1, 2, 3].map((number) => {\n    const nextNumber = number + 1;\n    return `A string containing the ${nextNumber}.`;\n  });\n\n  // good\n  [1, 2, 3].map((number, index) => ({\n    [index]: number,\n  }));\n\n  // 没有副作用的隐式返回\n  function foo(callback) {\n    const val = callback();\n    if (val === true) {\n      // 如果回调返回 true 执行\n    }\n  }\n\n  let bool = false;\n\n  // bad\n  foo(() => bool = true);\n\n  // good\n  foo(() => {\n    bool = true;\n  });\n  ```\n\n- [8.3](#arrows--paren-wrap) <a id=\"arrows--paren-wrap\"></a> **【推荐】** 如果表达式跨越多个行，用括号将其括起来，以获得更好的可读性。\n\n  > 原因? 它清楚地表明了函数的起点和终点。\n\n```javascript\n  // bad\n  ['get', 'post', 'put'].map(httpMethod => Object.prototype.hasOwnProperty.call(\n      httpMagicObjectWithAVeryLongName,\n      httpMethod,\n    )\n  );\n\n  // good\n  ['get', 'post', 'put'].map(httpMethod => (\n    Object.prototype.hasOwnProperty.call(\n      httpMagicObjectWithAVeryLongName,\n      httpMethod,\n    )\n  ));\n```\n\n- [8.4](#arrows--one-arg-parens) <a id=\"arrows--one-arg-parens\"></a> **【推荐】** 如果你的函数只有一个参数并且函数体没有大括号，就删除圆括号。 否则，为了保证清晰和一致性，请给参数加上括号。 注意：总是使用括号是可以接受的，在这种情况下，我们使用 [“always” option](https://eslint.org/docs/rules/arrow-parens#always) 来配置 eslint. eslint: [`arrow-parens`](https://eslint.org/docs/rules/arrow-parens.html)\n\n  > 原因？ 让代码看上去不那么乱。\n\n  ```javascript\n  // bad\n  [1, 2, 3].map((x) => x * x);\n\n  // good\n  [1, 2, 3].map(x => x * x);\n\n  // good\n  [1, 2, 3].map(number => (\n    `A long string with the ${number}. It’s so long that we don’t want it to take up space on the .map line!`\n  ));\n\n  // bad\n  [1, 2, 3].map(x => {\n    const y = x + 1;\n    return x * y;\n  });\n\n  // good\n  [1, 2, 3].map((x) => {\n    const y = x + 1;\n    return x * y;\n  });\n  ```\n\n- [8.5](#arrows--confusing) <a id=\"arrows--confusing\"></a> **【推荐】** 避免搞混箭头函数符号 (`=>`) 和比较运算符 (`<=`, `>=`)。 eslint: [`no-confusing-arrow`](https://eslint.org/docs/rules/no-confusing-arrow)\n\n  ```javascript\n  // bad\n  const itemHeight = item => item.height > 256 ? item.largeSize : item.smallSize;\n\n  // bad\n  const itemHeight = (item) => item.height > 256 ? item.largeSize : item.smallSize;\n\n  // good\n  const itemHeight = item => (item.height > 256 ? item.largeSize : item.smallSize);\n\n  // good\n  const itemHeight = (item) => {\n    const { height, largeSize, smallSize } = item;\n    return height > 256 ? largeSize : smallSize;\n  };\n  ```\n\n- [8.6](#whitespace--implicit-arrow-linebreak) <a id=\"whitespace--implicit-arrow-linebreak\"></a> **【推荐】** 在箭头函数用隐式 return 时强制将函数体的位置约束在箭头后。 eslint: [`implicit-arrow-linebreak`](https://eslint.org/docs/rules/implicit-arrow-linebreak)\n\n  ```javascript\n  // bad\n  (foo) =>\n    bar;\n\n  (foo) =>\n    (bar);\n\n  // good\n  (foo) => bar;\n  (foo) => (bar);\n  (foo) => (\n      bar\n  );\n  ```\n\n## 9. 类和构造器\n\n- [9.1](#constructors--use-class) <a id=\"constructors--use-class\"></a> **【推荐】** 尽量使用 `class`. 避免直接操作 `prototype` .\n\n  > 原因？ `class` 语法更简洁，更容易看懂。\n\n  ```javascript\n  // bad\n  function Queue(contents = []) {\n    this.queue = [...contents];\n  }\n  Queue.prototype.pop = function () {\n    const value = this.queue[0];\n    this.queue.splice(0, 1);\n    return value;\n  };\n\n  // good\n  class Queue {\n    constructor(contents = []) {\n      this.queue = [...contents];\n    }\n    pop() {\n      const value = this.queue[0];\n      this.queue.splice(0, 1);\n      return value;\n    }\n  }\n  ```\n\n- [9.2](#constructors--extends) <a id=\"constructors--extends\"></a> **【推荐】** 使用 `extends` 来实现继承。\n\n  > 原因？ 它是一个内置的方法，可以在不破坏 `instanceof` 的情况下继承原型功能。\n\n  ```javascript\n  // bad\n  const inherits = require('inherits');\n  function PeekableQueue(contents) {\n    Queue.apply(this, contents);\n  }\n  inherits(PeekableQueue, Queue);\n  PeekableQueue.prototype.peek = function () {\n    return this.queue[0];\n  };\n\n  // good\n  class PeekableQueue extends Queue {\n    peek() {\n      return this.queue[0];\n    }\n  }\n  ```\n\n- [9.3](#constructors--chaining) <a id=\"constructors--chaining\"></a> **【可选】** 类的成员方法，可以返回 `this`， 来实现链式调用。\n\n  ```javascript\n  // bad\n  Jedi.prototype.jump = function () {\n    this.jumping = true;\n    return true;\n  };\n\n  Jedi.prototype.setHeight = function (height) {\n    this.height = height;\n  };\n\n  const luke = new Jedi();\n  luke.jump(); // => true\n  luke.setHeight(20); // => undefined\n\n  // good\n  class Jedi {\n    jump() {\n      this.jumping = true;\n      return this;\n    }\n\n    setHeight(height) {\n      this.height = height;\n      return this;\n    }\n  }\n\n  const luke = new Jedi();\n\n  luke.jump()\n    .setHeight(20);\n  ```\n\n- [9.4](#constructors--tostring) <a id=\"constructors--tostring\"></a> **【可选】** 只要在确保能正常工作并且不产生任何副作用的情况下，编写一个自定义的 `toString()` 方法也是可以的。\n\n  ```javascript\n  class Jedi {\n    constructor(options = {}) {\n      this.name = options.name || 'no name';\n    }\n\n    getName() {\n      return this.name;\n    }\n\n    toString() {\n      return `Jedi - ${this.getName()}`;\n    }\n  }\n  ```\n\n- [9.5](#constructors--no-useless) <a id=\"constructors--no-useless\"></a> **【推荐】** 如果没有具体说明，类有默认的构造方法。一个空的构造函数或只是代表父类的构造函数是不需要写的。 eslint: [`no-useless-constructor`](https://eslint.org/docs/rules/no-useless-constructor)\n\n  ```javascript\n  // bad\n  class Jedi {\n    constructor() {}\n\n    getName() {\n      return this.name;\n    }\n  }\n\n  // bad\n  class Rey extends Jedi {\n    // 这种构造函数是不需要写的\n    constructor(...args) {\n      super(...args);\n    }\n  }\n\n  // good\n  class Rey extends Jedi {\n    constructor(...args) {\n      super(...args);\n      this.name = 'Rey';\n    }\n  }\n  ```\n\n- [9.6](#classes--no-duplicate-members) <a id=\"classes--no-duplicate-members\"></a> **【必须】** 避免定义重复的类成员。 eslint: [`no-dupe-class-members`](https://eslint.org/docs/rules/no-dupe-class-members)\n\n  > 原因？ 重复的类成员声明将会默认使用最后一个 - 具有重复的类成员可以说是一个bug。\n\n  ```javascript\n  // bad\n  class Foo {\n    bar() { return 1; }\n    bar() { return 2; }\n  }\n\n  // good\n  class Foo {\n    bar() { return 1; }\n  }\n\n  ```\n\n- [9.7] **【推荐】** 类成员要么引用 `this` ，要么声明为静态方法，除非一个外部库或框架需要使用某些非静态方法。当一个方法为非静态方法时，一般表明它在不同的实例上会表现得不同。\n\n## 10. 模块\n\n- [10.1](#modules--use-them) <a id=\"modules--use-them\"></a> **【可选】** 使用ES6的模块 (`import`/`export`) 语法来定义模块。\n\n  ```javascript\n  // bad\n  const AirbnbStyleGuide = require('./AirbnbStyleGuide');\n  module.exports = AirbnbStyleGuide.es6;\n\n  // ok\n  import AirbnbStyleGuide from './AirbnbStyleGuide';\n  export default AirbnbStyleGuide.es6;\n\n  // best\n  import { es6 } from './AirbnbStyleGuide';\n  export default es6;\n  ```\n\n- [10.2](#modules--no-wildcard) <a id=\"modules--no-wildcard\"></a> **【推荐】** 不要使用import * 通配符\n\n  > 原因？ 这确保你有单个默认的导出。\n\n  ```javascript\n  // bad\n  import * as AirbnbStyleGuide from './AirbnbStyleGuide';\n\n  // good\n  import AirbnbStyleGuide from './AirbnbStyleGuide';\n  ```\n\n- [10.3](#modules--no-export-from-import) <a id=\"modules--no-export-from-import\"></a> **【推荐】** 不要在import语句中直接export。\n\n  > 原因？ 虽然写在一行很简洁，但是有一个明确的导入和一个明确的导出能够保证一致性。\n\n  ```javascript\n  // bad\n  // filename es6.js\n  export { es6 as default } from './AirbnbStyleGuide';\n\n  // good\n  // filename es6.js\n  import { es6 } from './AirbnbStyleGuide';\n  export default es6;\n  ```\n\n- [10.4](#import/no-duplicates) <a id=\"import/no-duplicates\"></a> **【必须】** 对于同一个路径，只在一个地方引入所有需要的东西。\n     eslint: [`no-duplicates`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-duplicates.md)\n\n  > 原因？ 对于同一个路径，如果存在多行引入，会使代码更难以维护。\n\n  ```javascript\n  // bad\n  import foo from 'foo';\n  // … 其他导入 … //\n  import { named1, named2 } from 'foo';\n\n  // good\n  import foo, { named1, named2 } from 'foo';\n\n  // good\n  import foo, {\n    named1,\n    named2,\n  } from 'foo';\n  ```\n\n- [10.5](#modules--no-mutable-exports) <a id=\"modules--no-mutable-exports\"></a> **【推荐】** 不要导出可变的引用。\n     eslint: [`import/no-mutable-exports`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-mutable-exports.md)\n\n  > 原因？ 在一般情况下，应该避免导出可变引用。虽然在某些特殊情况下，可能需要这样，但是一般情况下只需要导出常量引用。\n\n  ```javascript\n  // bad\n  let foo = 3;\n  export { foo };\n\n  // good\n  const foo = 3;\n  export { foo };\n  ```\n\n- [10.6](#modules--prefer-default-export) <a id=\"modules--prefer-default-export\"></a> **【可选】** 在只有单一导出的模块里，用 export default 更好。\n     eslint: [`import/prefer-default-export`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/prefer-default-export.md)\n\n  > 原因？ 鼓励更多的模块只做单一导出，会增强代码的可读性和可维护性。\n\n  ```javascript\n  // bad\n  export function foo() {}\n\n  // good\n  export default function foo() {}\n  ```\n\n- [10.7](#modules--imports-first) <a id=\"modules--imports-first\"></a> **【必须】** 将所有的 `import`s 语句放在其他语句之前。\n     eslint: [`import/first`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/first.md)\n\n    > 原因？ 将所有的 `import`s 提到顶部，可以防止某些诡异行为的发生。\n\n  ```javascript\n  // bad\n  import foo from 'foo';\n  foo.init();\n\n  import bar from 'bar';\n\n  // good\n  import foo from 'foo';\n  import bar from 'bar';\n\n  foo.init();\n  ```\n\n- [10.8](#modules--multiline-imports-over-newlines) <a id=\"modules--multiline-imports-over-newlines\"></a> **【可选】** 多行引入应该像多行数组和对象字面量一样缩进。\n\n  > 原因？ 这里的花括号和其他地方的花括号是一样的，遵循相同的缩进规则。末尾的逗号也是一样的。\n\n  ```javascript\n  // bad\n  import {longNameA, longNameB, longNameC, longNameD, longNameE} from 'path';\n\n  // good\n  import {\n    longNameA,\n    longNameB,\n    longNameC,\n    longNameD,\n    longNameE,\n  } from 'path';\n  ```\n\n- [10.9](#modules--no-webpack-loader-syntax) <a id=\"modules--no-webpack-loader-syntax\"></a> **【推荐】** 在模块导入语句中禁止使用 Webpack 加载器语法。\n     eslint: [`import/no-webpack-loader-syntax`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-webpack-loader-syntax.md)\n\n    > 原因？ 因为在导入语句中使用 webpack 语法，会将代码和打包工具耦合在一起。应该在 `webpack.config.js` 中使用加载器语法。\n\n  ```javascript\n  // bad\n  import fooSass from 'css!sass!foo.scss';\n  import barCss from 'style!css!bar.css';\n\n  // good\n  import fooSass from 'foo.scss';\n  import barCss from 'bar.css';\n  ```\n\n## 11. 迭代器和发生器\n\n- [11.1](#iterators--nope) <a id=\"iterators--nope\"></a> **【推荐】** 不要使用迭代器。 推荐使用 JavaScript 的高阶函数代替 `for-in` 。 eslint: [`no-iterator`](https://eslint.org/docs/rules/no-iterator.html) [`no-restricted-syntax`](https://eslint.org/docs/rules/no-restricted-syntax)\n\n  > 原因？ 这有助于不可变性原则。 使用带有返回值的纯函数比使用那些带有副作用的方法，更具有可读性。\n\n  > 使用 `map()` / `every()` / `filter()` / `find()` / `findIndex()` / `reduce()` / `some()` / ... 遍历数组， 和使用 `Object.keys()` / `Object.values()` / `Object.entries()` 迭代你的对象生成数组。\n\n  ```javascript\n  const numbers = [1, 2, 3, 4, 5];\n\n  // bad\n  let sum = 0;\n  for (let num of numbers) {\n    sum += num;\n  }\n  sum === 15;\n\n  // good\n  let sum = 0;\n  numbers.forEach((num) => {\n    sum += num;\n  });\n  sum === 15;\n\n  // best (use the functional force)\n  const sum = numbers.reduce((total, num) => total + num, 0);\n  sum === 15;\n\n  // bad\n  const increasedByOne = [];\n  for (let i = 0; i < numbers.length; i++) {\n    increasedByOne.push(numbers[i] + 1);\n  }\n\n  // good\n  const increasedByOne = [];\n  numbers.forEach((num) => {\n    increasedByOne.push(num + 1);\n  });\n\n  // best (keeping it functional)\n  const increasedByOne = numbers.map(num => num + 1);\n  ```\n\n- [11.2](#generators--nope) <a id=\"generators--nope\"></a> **【可选】** 现在不要使用generator。\n\n  > 原因？ 它们不能很好的转译为 ES5。但可以在Nodejs中使用。*\n\n- [11.3](#generators--spacing) <a id=\"generators--spacing\"></a> **【推荐】** 如果你必须要使用generator，请确保正确使用空格。 eslint: [`generator-star-spacing`](https://eslint.org/docs/rules/generator-star-spacing)\n\n  > 原因？ `function` 和 `*` 是同一个概念关键字的一部分 - `*` 不是 `function` 的修饰符， `function*` 是一个不同于 `function` 的构造器。\n\n  ```javascript\n  // bad\n  function * foo() {\n    // ...\n  }\n\n  // bad\n  const bar = function * () {\n    // ...\n  };\n\n  // bad\n  const baz = function *() {\n    // ...\n  };\n\n  // bad\n  const quux = function*() {\n    // ...\n  };\n\n  // bad\n  function*foo() {\n    // ...\n  }\n\n  // bad\n  function *foo() {\n    // ...\n  }\n\n  // very bad\n  function\n  *\n  foo() {\n    // ...\n  }\n\n  // very bad\n  const wat = function\n  *\n  () {\n    // ...\n  };\n\n  // good\n  function* foo() {\n    // ...\n  }\n\n  // good\n  const foo = function* () {\n    // ...\n  };\n  ```\n\n## 12. 属性\n\n- [12.1](#properties--dot) <a id=\"properties--dot\"></a> **【推荐】** 访问属性时使用点符号。 eslint: [`dot-notation`](https://eslint.org/docs/rules/dot-notation.html)\n\n  ```javascript\n  const luke = {\n    jedi: true,\n    age: 28,\n  };\n\n  // bad\n  const isJedi = luke['jedi'];\n\n  // good\n  const isJedi = luke.jedi;\n  ```\n\n- [12.2](#properties--bracket) <a id=\"properties--bracket\"></a> **【可选】** 使用变量访问属性时，用 `[]`表示法。\n\n  ```javascript\n  const luke = {\n    jedi: true,\n    age: 28,\n  };\n\n  function getProp(prop) {\n    return luke[prop];\n  }\n\n  const isJedi = getProp('jedi');\n  ```\n\n- [12.3](#es2016-properties--exponentiation-operator) <a id=\"es2016-properties--exponentiation-operator\"></a> **【推荐】** 计算指数时，可以使用 `**` 运算符。 eslint: [`no-restricted-properties`](https://eslint.org/docs/rules/no-restricted-properties).\n\n  ```javascript\n  // bad\n  const binary = Math.pow(2, 10);\n\n  // good\n  const binary = 2 ** 10;\n  ```\n\n## 13. 变量\n\n- [13.1](#variables--const) <a id=\"variables--const\"></a> **【必须】** 变量应先声明再使用，禁止引用任何未声明的变量，除非你明确知道引用的变量存在于当前作用域链上。禁止不带任何关键词定义变量，这样做将会创建一个全局变量，污染全局命名空间，造成程序意料之外的错误。 eslint: [`no-undef`](https://eslint.org/docs/rules/no-undef) [`prefer-const`](https://eslint.org/docs/rules/prefer-const)\n\n  ```javascript\n  // bad, 这会创建一个全局变量\n  superPower = new SuperPower();\n\n  // good\n  const superPower = new SuperPower();\n\n  // bad, 容易污染外部变量\n  let superPower = 'a';\n  (function() {\n    superPower = 'b';\n  })();\n  console.log(superPower);\n\n  // good\n  let superPower = 'a';\n  (function() {\n    let superPower = 'b';\n  })();\n  console.log(superPower);\n\n  // bad, 更常见的情况是这样的，在 for 循环里的 i 将会污染外部的变量 i\n  let i = 1;\n  (function() {\n    for (i = 0; i < 10; i++) {\n      console.log('inside', i);\n    }\n\n    console.log('outside', i)\n  })();\n  console.log('global', i);\n\n  // good\n  let i = 1;\n  (function() {\n    // i 的作用域在 for 循环内\n    for (let i = 0; i < 10; i++) {\n      console.log('inside i', i);\n    }\n\n    // 如果真的需要在 for 循环外使用循环变量，应该先定义在外部\n    let j;\n\n    for (j = 0; j < 10; j++) {\n      console.log('inside j:', j);\n    }\n\n    console.log('outside j', j);\n  })();\n  console.log('global', i);\n  ```\n\n- [13.2](#variables--one-const) <a id=\"variables--one-const\"></a> **【推荐】** 声明多个变量应该分开声明，避免使用 `,` 一次声明多个变量。 eslint: [`one-var`](https://eslint.org/docs/rules/one-var.html)\n\n  > 原因？ 这样更容易添加新的变量声明，不必担心是使用 `;` 还是使用 `,` 所带来的代码差异。使用版本管理工具如 git ，最后那行的 `;` 就不会被标记为修改成 `,`。 并且可以通过 debugger 逐步查看每个声明，而不是立即跳过所有声明。\n\n  ```javascript\n  // bad\n  const items = getItems(),\n      goSportsTeam = true,\n      dragonball = 'z';\n\n  // bad\n  const items = getItems(),\n      goSportsTeam = true;\n      // 定义成了全局变量\n      dragonball = 'z';\n\n  // good\n  const items = getItems();\n  const goSportsTeam = true;\n  const dragonball = 'z';\n  ```\n\n- [13.3](#variables--const-let-group) <a id=\"variables--const-let-group\"></a> **【推荐】** 把 `const` 声明语句放在一起，把 `let` 声明语句放在一起。\n\n  > 原因？ 这在后边如果需要根据前边的赋值变量指定一个变量时很有用，且更容易知道哪些变量是不希望被修改的。\n\n  ```javascript\n  // bad\n  let i;\n  const items = getItems();\n  let dragonball;\n  const goSportsTeam = true;\n  let len;\n\n  // good\n  const goSportsTeam = true;\n  const items = getItems();\n  let dragonball;\n  let i;\n  let length;\n  ```\n\n- [13.4](#variables--define-where-used) <a id=\"variables--define-where-used\"></a> **【推荐】** 在你真正需要使用到变量的代码块内定义变量。\n\n  > 原因？ `let` 和 `const` 是块级作用域而不是函数作用域，不存在变量提升的情况。\n\n  ```javascript\n  // bad, 不必要的函数调用\n  function checkName(hasName) {\n    const name = getName();\n\n    if (hasName === 'test') {\n      return false;\n    }\n\n    if (name === 'test') {\n      this.setName('');\n      return false;\n    }\n\n    return name;\n  }\n\n  // good\n  function checkName(hasName) {\n    if (hasName === 'test') {\n      return false;\n    }\n\n    const name = getName();\n\n    if (name === 'test') {\n      this.setName('');\n      return false;\n    }\n\n    return name;\n  }\n  ```\n\n- [13.5](#variables--no-chain-assignment) <a id=\"variables--no-chain-assignment\"></a> **【必须】** 不要链式变量赋值。 eslint: [`no-multi-assign`](https://eslint.org/docs/rules/no-multi-assign)\n\n  > 原因？ 链式变量赋值会创建隐式全局变量。\n\n  ```javascript\n  // bad\n  (function example() {\n    /*\n    * JavaScript 把它解释为\n    * let a = ( b = ( c = 1 ) );\n    * let 关键词只适用于变量 a，变量 b 和变量 c 则变成了全局变量。\n    */\n    let a = b = c = 1;\n  }());\n\n  // throws ReferenceError\n  console.log(a);\n  // 1\n  console.log(b);\n  // 1\n  console.log(c);\n\n  // good\n  (function example() {\n    let a = 1;\n    let b = a;\n    let c = a;\n  }());\n\n  // throws ReferenceError\n  console.log(a);\n  // throws ReferenceError\n  console.log(b);\n  // throws ReferenceError\n  console.log(c);\n\n  // 对于 `const` 也一样\n  ```\n\n- [13.6](#variables--unary-increment-decrement) <a id=\"variables--unary-increment-decrement\"></a> **【必须】** 避免使用不必要的递增和递减操作符 (`++`, `--`)。 eslint [`no-plusplus`](https://eslint.org/docs/rules/no-plusplus)\n\n  > 原因？ 在eslint文档中，一元操作符 `++` 和 `--`会自动添加分号，不同的空白可能会改变源代码的语义。建议使用 `num += 1` 这样的语句来做递增和递减，而不是使用 `num++` 或 `num ++` 。同时 `++num` 和 `num++` 的差异也使代码的可读性变差。不必要的增量和减量语句会导致无法预先明确递增/预递减值，这可能会导致程序中的意外行为。\n\n  > 但目前依然允许在 for loop 中使用 `++`、`--` 的语法，但依然建议尽快迁移到 `+= 1`、`-= 1` 的语法。 [#22](https://git.woa.com/standards/javascript/issues/22)\n\n  ```javascript\n  // bad, i = 11, j = 20\n  let i = 10;\n  let j = 20;\n  i ++\n  j\n\n  // bad, i = 10, j = 21\n  let i = 10;\n  let j = 20;\n  i\n  ++\n  j\n\n  // bad\n  const array = [1, 2, 3];\n  let num = 1;\n  num++;\n  --num;\n\n  // not good, just acceptable for upforward compatible.\n  let sum = 0;\n  let truthyCount = 0;\n  for (let i = 0; i < array.length; i++) {\n    let value = array[i];\n    sum += value;\n    if (value) {\n      truthyCount++;\n    }\n  }\n\n  // good\n  const array = [1, 2, 3];\n  let num = 1;\n  num += 1;\n  num -= 1;\n\n  // good\n  const sum = array.reduce((a, b) => a + b, 0);\n  const truthyCount = array.filter(Boolean).length;\n  ```\n\n- [13.7](#variables--linebreak) <a id=\"variables--linebreak\"></a> **【必须】** 避免在赋值语句 `=` 前后换行。如果你的代码单行长度超过了 [`max-len`](https://eslint.org/docs/rules/max-len.html) 定义的长度而不得不换行，那么使用括号包裹。 eslint [`operator-linebreak`](https://eslint.org/docs/rules/operator-linebreak.html).\n\n  > 原因？ 在 `=` 前后换行，可能混淆赋的值。\n\n  ```javascript\n  // bad\n  const foo\n    = 'superLongLongLongLongLongLongLongLongString';\n\n  // bad\n  const bar =\n    superLongLongLongLongLongLongLongLongFunctionName();\n\n  // bad\n  const fullHeight = borderTop +\n                 innerHeight +\n                 borderBottom;\n\n  // bad\n  const anotherHeight = borderTop +\n    innerHeight +\n    borderBottom;\n\n  // bad\n  const thirdHeight = (\n    borderTop +\n    innerHeight +\n    borderBottom\n  );\n\n  // good - max-len 会忽略字符串，直接写后面即可。\n  const foo = 'superLongLongLongLongLongLongLongLongString';\n\n  // good\n  const bar = (\n    superLongLongLongLongLongLongLongLongFunctionName()\n  );\n\n  // good\n  const fullHeight = borderTop\n                   + innerHeight\n                   + borderBottom;\n\n  // good\n  const anotherHeight = borderTop\n    + innerHeight\n    + borderBottom;\n\n  // good\n  const thirdHeight = (\n    borderTop\n    + innerHeight\n    + borderBottom\n  );\n\n  ```\n\n- [13.8](#variables--no-unused-vars) <a id=\"variables--no-unused-vars\"></a> **【必须】** 禁止定义了变量却不使用它。 eslint: [`no-unused-vars`](https://eslint.org/docs/rules/no-unused-vars)\n\n  > 原因? 在代码里到处定义变量却没有使用它，不完整的代码结构看起来像是个代码错误。即使没有使用，但是定义变量仍然需要消耗资源，并且对阅读代码的人也会造成困惑，不知道这些变量是要做什么的。\n\n  ```javascript\n  // bad\n  let some_unused_var = 42;\n\n  // bad，定义了变量不意味着就是使用了\n  let y = 10;\n  y = 5;\n\n  // bad，对自身的操作并不意味着使用了\n  let z = 0;\n  z = z + 1;\n\n  // bad, 未使用的函数参数\n  function getX(x, y) {\n      return x;\n  }\n\n  // good\n  function getXPlusY(x, y) {\n    return x + y;\n  }\n\n  let x = 1;\n  let y = a + 2;\n\n  alert(getXPlusY(x, y));\n\n  /*\n   * 有时候我们想要提取某个对象排除了某个属性外的其他属性，会用 rest 参数解构对象\n   * 这时候 type 虽然未使用，但是仍然被定义和赋值，这也是一种空间的浪费\n   * type 的值是 'a'\n   * coords 的值是 data 对象，但是没有 type 属性 { example1: 'b', example2: 'c' }\n   */\n  let data = { type: 'a', example1: 'b', example2: 'c' }\n  let { type, ...coords } = data;\n\n  /*\n   * 有时候如果定义了一个基类或者接口（Typescript）\n   * 基类或接口中该方法需要定义这个参数，但消费参数是由子类自行实现的\n   * 可以通过在变量名前加下划线的方式来表示该变量是未使用的\n   */\n  export class Model {\n    toList(_isCompact) {\n      // 待子类实现\n    }\n  }\n\n  export class MyModel extends Model {\n    data = [];\n    toList(isCompact) {\n      return isCompact ? this.data.flat() : this.data;\n    }\n  }\n  ```\n\n## 14. 变量提升\n\n- [14.1](#hoisting--about) <a id=\"hoisting--about\"></a> **【可选】** `var` 定义的变量会被提升到函数作用域范围内的最顶部，但是对它的赋值是不会被提升的，因此在函数顶部相当于定义了变量，但是值是 `undefined`。`const` 和 `let` 声明的变量受到一个称之为 \"暂时性死区\" [(Temporal Dead Zones ，简称 TDZ)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_dead_zone) 的新概念保护，因此在 \"暂时性死区\" 内部的 `const` 和 `let` 变量，都需要先声明再使用，否则会报错。详情可以阅读  [typeof 不再安全](https://web.archive.org/web/20200121061528/http://es-discourse.com/t/why-typeof-is-no-longer-safe/15) 这篇文章。\n\n  ```javascript\n  // notDefined 未定义 (假设没有定义的同名全局变量)\n  function example() {\n    // => throws a ReferenceError\n    console.log(notDefined);\n  }\n\n  /*\n  * 函数体内部因存在 var 变量声明，因此在引用变量的语句之前，变量提升就已经起作用了\n  * 注意: 真正的值 `true` 不会被提升。\n  */\n  function example() {\n    // => undefined\n    console.log(declaredButNotAssigned);\n    var declaredButNotAssigned = true;\n  }\n\n  /*\n  * 解释器将变量提升到函数的顶部\n  * 这意味着我们可以将上边的例子重写为：\n  */\n  function example() {\n    let declaredButNotAssigned;\n    // => undefined\n    console.log(declaredButNotAssigned);\n    declaredButNotAssigned = true;\n  }\n\n  // 使用 const 和 let\n  function example() {\n    // => throws a ReferenceError\n    console.log(declaredButNotAssigned);\n    // => throws a ReferenceError\n    console.log(typeof declaredButNotAssigned);\n    const declaredButNotAssigned = true;\n  }\n  ```\n\n- [14.2](#hoisting--anon-expressions) <a id=\"hoisting--anon-expressions\"></a> **【可选】** 匿名函数赋值表达式提升变量名，而不是函数赋值。\n\n  ```javascript\n  function example() {\n    // => undefined\n    console.log(anonymous);\n\n    // => TypeError anonymous is not a function\n    anonymous();\n\n    var anonymous = function () {\n      console.log('anonymous function expression');\n    };\n  }\n  ```\n\n- [14.3](#hoisting--named-expressions) <a id=\"hoisting--named-expressions\"></a> **【可选】** 命名函数表达式提升的是变量名，而不是函数名或者函数体。\n\n  ```javascript\n  function example() {\n    // => undefined\n    console.log(named);\n\n    // => TypeError named is not a function\n    named();\n\n    // => ReferenceError superPower is not defined\n    superPower();\n\n    var named = function superPower() {\n      console.log('Flying');\n    };\n  }\n\n  // 当函数名和变量名相同时也是如此。\n  function example() {\n    // => undefined\n    console.log(named);\n\n    // => TypeError named is not a function\n    named();\n\n    var named = function named() {\n      console.log('named');\n    };\n  }\n  ```\n\n- [14.4](#hoisting--declarations) <a id=\"hoisting--declarations\"></a> **【可选】** 函数声明提升其名称和函数体。\n\n  ```javascript\n  function example() {\n    // => Flying\n    superPower();\n\n    function superPower() {\n      console.log('Flying');\n    }\n  }\n  ```\n\n  - 更多信息请参考 [Ben Cherry](http://www.adequatelygood.com/) 的 [JavaScript Scoping & Hoisting](http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting/)。\n\n## 15. 比较运算符和等号\n\n- [15.1](#comparison--eqeqeq) <a id=\"comparison--eqeqeq\"></a> **【推荐】** 使用 `===` 和 `!==` 而不是 `==` 和 `!=`。 eslint: [`eqeqeq`](https://eslint.org/docs/rules/eqeqeq.html)\n\n  > 原因？`==` 和 `!=` 存在类型转换，会得到和 `===`、`!==` 不一样的结果\n\n  ```javascript\n  // bad, true\n  undefined == null\n  // good, false\n  undefined === null\n\n  // bad, true\n  '0' == 0\n  // good, false\n  '0' === 0\n\n  // bad, true\n  0 == false\n  // good, false\n  0 === false\n\n  // bad, true\n  '' == false\n  // good, false\n  '' === false\n  ```\n\n- [15.2](#comparison--if) <a id=\"comparison--if\"></a> **【可选】** 条件语句，例如 `if` 语句使用 `ToBoolean` 的抽象方法来计算表达式的结果，并始终遵循以下简单的规则：\n\n  - **Objects** 的取值为： **true**，{} 和 [] 的取值也为: **true**\n  - **Undefined** 的取值为： **false**\n  - **Null** 的取值为： **false**\n  - **Booleans** 的取值为： **布尔值的取值**\n  - **Numbers** 的取值为：如果为 **+0, -0, or NaN** 值为 **false** 否则为 **true**\n  - **Strings** 的取值为: 如果是一个空字符串 `''` 值为 **false** 否则为 **true**\n\n  ```javascript\n  if ([0] && []) {\n    // true， 数组（即使是空的）是一个对象，对象的取值为 true\n  }\n  ```\n\n- [15.3](#comparison--shortcuts) <a id=\"comparison--shortcuts\"></a> **【推荐】** 对于布尔值（在明确知道是布尔值的情况下）使用简写，但是对于字符串和数字进行显式比较。\n\n  ```javascript\n  // bad\n  if (isValid === true) {\n    // ...\n  }\n\n  // good\n  if (isValid) {\n    // ...\n  }\n\n  // bad\n  if (name) {\n    // ...\n  }\n\n  // good\n  if (name !== '') {\n    // ...\n  }\n\n  // bad\n  if (collection.length) {\n    // ...\n  }\n\n  // good\n  if (collection.length > 0) {\n    // ...\n  }\n  ```\n\n- [15.4](#comparison--moreinfo) <a id=\"comparison--moreinfo\"></a> **【可选】** 关于布尔值转换和条件语句，详细信息可参阅 Angus Croll 的 [Truth Equality and JavaScript](https://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/#more-2108) 这篇文章。\n\n- [15.5](#comparison--switch-blocks) <a id=\"comparison--switch-blocks\"></a> **【必须】** 在 `case` 和 `default` 的子句中，如果存在声明 (例如. `let`, `const`, `function`, 和 `class`)，使用大括号来创建块级作用域。 eslint: [`no-case-declarations`](https://eslint.org/docs/rules/no-case-declarations.html)\n\n  > 原因？ 变量声明的作用域在整个 switch 语句内，但是只有在 case 条件为真时变量才会被初始化。 当多个 `case` 语句定义相同的变量时，就会导致变量覆盖的问题。\n\n  ```javascript\n  // bad\n  switch (foo) {\n    case 1:\n      let x = 1;\n      break;\n    case 2:\n      const y = 2;\n      break;\n    case 3:\n      function f() {\n        // ...\n      }\n      break;\n    default:\n      class C {}\n  }\n\n  // good\n  switch (foo) {\n    case 1: {\n      let x = 1;\n      break;\n    }\n    case 2: {\n      const y = 2;\n      break;\n    }\n    case 3: {\n      function f() {\n        // ...\n      }\n      break;\n    }\n    case 4:\n      bar();\n      break;\n    default: {\n      class C {}\n    }\n  }\n  ```\n\n- [15.6](#comparison--nested-ternaries) <a id=\"comparison--nested-ternaries\"></a> **【推荐】** 三元表达式不应该嵌套，通常是单行表达式，如果确实需要多行表达式，那么应该考虑使用条件语句。 eslint: [`no-nested-ternary`](https://eslint.org/docs/rules/no-nested-ternary.html)\n\n  ```javascript\n  // bad\n  const foo = maybe1 > maybe2\n    ? \"bar\"\n    : value1 > value2 ? \"baz\" : null;\n\n  // 分离为两个三元表达式\n  const maybeNull = value1 > value2 ? 'baz' : null;\n\n  // better\n  const foo = maybe1 > maybe2\n    ? 'bar'\n    : maybeNull;\n\n  // best\n  const foo = maybe1 > maybe2 ? 'bar' : maybeNull;\n  ```\n\n- [15.7](#comparison--unneeded-ternary) <a id=\"comparison--unneeded-ternary\"></a> **【推荐】** 避免不必要的三元表达式。 eslint: [`no-unneeded-ternary`](https://eslint.org/docs/rules/no-unneeded-ternary.html)\n\n  ```javascript\n  // bad\n  const foo = a ? a : b;\n  const bar = c ? true : false;\n  const baz = c ? false : true;\n\n  // good\n  const foo = a || b;\n  const bar = !!c;\n  const baz = !c;\n  ```\n\n- [15.8](#comparison--no-mixed-operators) <a id=\"comparison--no-mixed-operators\"></a> **【必须】** 使用混合运算符时，使用小括号括起来需要一起计算的部分，只要觉得有必要，那么尽可能地用括号让代码的优先级更明显。大家都能理解的运算符 `+`、`-`、`**` 不要求添加括号。但我们建议在 `*`、`/` 之间添加括号，因为乘除运算符混写写的比较长的时候容易产生歧义。 eslint: [`no-mixed-operators`](https://eslint.org/docs/rules/no-mixed-operators.html)\n\n  > 原因？ 这能提高可读性并且表明开发人员的意图。\n\n  ```javascript\n  // bad\n  const foo = a && b < 0 || c > 0 || d + 1 === 0;\n\n  // bad\n  const bar = a ** b - 5 % d;\n\n  // bad, 可能陷入一种 (a || b) && c 的思考\n  if (a || b && c) {\n    return d;\n  }\n\n  // bad\n  const bar1 = a + b / c * (d / e);\n\n  // good\n  const foo = (a && b < 0) || (c > 0) || (d + 1 === 0);\n\n  // good\n  const bar = (a ** b) - (5 % d);\n\n  // good\n  if (a || (b && c)) {\n    return d;\n  }\n\n  // good\n  const bar1 = a + (b / c) * (d / e);\n  ```\n\n## 16. 代码块\n\n- [16.1](#blocks--braces) <a id=\"blocks--braces\"></a> **【必须】** 当有多行代码块的时候，应使用大括号包裹。 eslint: [`nonblock-statement-body-position`](https://eslint.org/docs/rules/nonblock-statement-body-position)\n\n  ```javascript\n  // bad\n  if (test)\n    return false;\n\n  // bad\n  let condition = true;\n  let test = 1;\n  // 在缩进不规范的时候，容易造成误解\n  if (condition)\n    condition = false;\n    test = 2;\n\n  // good\n  if (test) return false;\n\n  // good\n  if (test) {\n    return false;\n  }\n\n  // bad\n  function foo() { return false; }\n\n  // good\n  function bar() {\n    return false;\n  }\n  ```\n\n- [16.2](#blocks--cuddled-elses) <a id=\"blocks--cuddled-elses\"></a> **【必须】** 如果你使用的是 `if` 和 `else` 的多行代码块，则将 `else` 语句放在 `if` 块闭括号同一行的位置。 eslint: [`brace-style`](https://eslint.org/docs/rules/brace-style.html)\n\n  ```javascript\n  // bad\n  if (test) {\n    thing1();\n    thing2();\n  }\n  else {\n    thing3();\n  }\n\n  // good\n  if (test) {\n    thing1();\n    thing2();\n  } else {\n    thing3();\n  }\n  ```\n\n- [16.3](#blocks--no-else-return) <a id=\"blocks--no-else-return\"></a> **【推荐】** 如果一个 `if` 块总是会执行 return 语句，那么接下来的 `else` 块就没有必要了。 如果一个包含 `return` 语句的 `else if` 块，在一个包含了 `return` 语句的 `if` 块之后，那么可以拆成多个 `if` 块。 eslint: [`no-else-return`](https://eslint.org/docs/rules/no-else-return)\n\n  ```javascript\n  // bad\n  function foo() {\n    if (x) {\n      return x;\n    } else {\n      return y;\n    }\n  }\n\n  // bad\n  function cats() {\n    if (x) {\n      return x;\n    } else if (y) {\n      return y;\n    }\n  }\n\n  // bad\n  function dogs() {\n    if (x) {\n      return x;\n    } else {\n      if (y) {\n        return y;\n      }\n    }\n  }\n\n  // good\n  function foo() {\n    if (x) {\n      return x;\n    }\n\n    return y;\n  }\n\n  // good\n  function cats() {\n    if (x) {\n      return x;\n    }\n\n    if (y) {\n      return y;\n    }\n  }\n\n  // good\n  function dogs(x) {\n    if (x) {\n      if (z) {\n        return y;\n      }\n    } else {\n      return z;\n    }\n  }\n  ```\n\n## 17. 控制语句\n\n- [17.1](#control-statements) <a id=\"control-statements\"></a> **【推荐】** 如果你的控制语句 (`if`, `while` 等) 太长或者超过了一行最大长度的限制，则可以将每个条件（或组）放入一个新的行。 逻辑运算符应该在行的开始。\n\n  > 原因？ 在行的开头要求运算符保持对齐，并遵循类似于方法链的模式。这提高了可读性，并且使更复杂的逻辑更容易直观的被理解。\n\n  ```javascript\n  // bad\n  if ((foo === 123 || bar === 'abc') && doesItLookGoodWhenItBecomesThatLong() && isThisReallyHappening()) {\n    thing1();\n  }\n\n  // bad\n  if (foo === 123 &&\n    bar === 'abc') {\n    thing1();\n  }\n\n  // bad\n  if (foo === 123\n    && bar === 'abc') {\n    thing1();\n  }\n\n  // bad\n  if (\n    foo === 123 &&\n    bar === 'abc'\n  ) {\n    thing1();\n  }\n\n  // good\n  if (\n    foo === 123\n    && bar === 'abc'\n  ) {\n    thing1();\n  }\n\n  // good\n  if (\n    (foo === 123 || bar === 'abc')\n    && doesItLookGoodWhenItBecomesThatLong()\n    && isThisReallyHappening()\n  ) {\n    thing1();\n  }\n\n  // good\n  if (foo === 123 && bar === 'abc') {\n    thing1();\n  }\n  ```\n\n- [17.2](#control-statements--value-selection) <a id=\"control-statements--value-selection\"></a> **【必须】** 不要使用选择操作符代替控制语句。\n\n  ```javascript\n  // bad\n  !isRunning && startRunning();\n\n  // good\n  if (!isRunning) {\n    startRunning();\n  }\n  ```\n\n## 18. 注释\n\n- [18.1](#comments--multiline) <a id=\"comments--multiline\"></a> **【必须】** 使用 `/* ... */` 来进行多行注释。\n\n  ```javascript\n  // bad\n  // make() returns a new element\n  // based on the passed in tag name\n  //\n  // @param {String} tag\n  // @return {Element} element\n  function make(tag) {\n\n    // ...\n\n    return element;\n  }\n\n  // good\n  /*\n   * make() returns a new element\n   * based on the passed-in tag name\n   */\n  function make(tag) {\n\n    // ...\n\n    return element;\n  }\n  ```\n\n- [18.2](#comments--singleline) <a id=\"comments--singleline\"></a> **【推荐】** 使用 `//` 进行单行注释。 将单行注释放在需要注释的行的上方新行。 建议在注释之前放一个空行，除非它在块的第一行。但如果一段代码每行都包含注释，允许不加分行。\n\n  ```javascript\n  // bad\n  const active = true;  // is current tab\n\n  // good\n  // is current tab\n  const active = true;\n\n  // bad\n  function getType() {\n    console.log('fetching type...');\n    // set the default type to 'no type'\n    const type = this.type || 'no type';\n\n    return type;\n  }\n\n  // good\n  function getType() {\n    console.log('fetching type...');\n\n    // set the default type to 'no type'\n    const type = this.type || 'no type';\n\n    return type;\n  }\n\n  // also good\n  function getType() {\n    // set the default type to 'no type'\n    const type = this.type || 'no type';\n\n    return type;\n  }\n  ```\n\n- [18.3](#comments--spaces) <a id=\"comments--spaces\"></a> **【必须】** 用一个空格开始所有的注释，使它更容易阅读。 eslint: [`spaced-comment`](https://eslint.org/docs/rules/spaced-comment)\n\n  ```javascript\n  // bad\n  //is current tab\n  const active = true;\n\n  // good\n  // is current tab\n  const active = true;\n\n  // bad\n  /**\n   *make() returns a new element\n   *based on the passed-in tag name\n   */\n  function make(tag) {\n\n    // ...\n\n    return element;\n  }\n\n  // good\n  /**\n   * make() returns a new element\n   * based on the passed-in tag name\n   */\n  function make(tag) {\n\n    // ...\n\n    return element;\n  }\n  ```\n\n- [18.4](#comments--actionitems) <a id=\"comments--actionitems\"></a> **【推荐】** 使用 `FIXME` 或者 `TODO` 开始你的注释可以帮助其他开发人员快速了解相应代码，如果你提出了一个需要重新讨论的问题，或者你对需要解决的问题提出的解决方案。 这些不同于其他普通注释，因为它们是可操作的。 这些操作是 `FIXME: -- 需要解决这个问题` 或者 `TODO: -- 需要被实现`。\n\n- [18.5](#comments--fixme) <a id=\"comments--fixme\"></a> **【推荐】** 使用 `// FIXME:` 注释问题。\n\n  ```javascript\n  class Calculator extends Abacus {\n    constructor() {\n      super();\n\n      // FIXME: 这里不应该使用全局变量\n      total = 0;\n    }\n  }\n  ```\n\n- [18.6](#comments--todo) <a id=\"comments--todo\"></a> **【推荐】** 使用 `// TODO:` 注释解决问题的方法。\n\n  ```javascript\n  class Calculator extends Abacus {\n    constructor() {\n      super();\n\n      // TODO: total 应该由一个 param 的选项配置\n      this.total = 0;\n    }\n  }\n  ```\n\n- [18.7](#comments--jsdoc) <a id=\"comments--jsdoc\"></a> **【必须】** `/** ... */` 风格（首行有两个 *）的块级多行注释仅能被用于 JSDoc。\n\n  ```javascript\n  class Calculator {\n    /**\n     * 用于将多个数字相加求和\n     *\n     * @param {number[]} nums 一系列用于相加的数字\n     * @returns {number} 最终的和\n     */\n    add(...nums) {\n      return nums.reduce((res, num) => res + num, 0);\n    }\n  }\n  ```\n\n## 19. 空白\n\n- [19.1](#whitespace--spaces) <a id=\"whitespace--spaces\"></a> **【推荐】** 使用 tabs (空格字符) 设置为2个空格。 eslint: [`indent`](https://eslint.org/docs/rules/indent.html)\n\n  ```javascript\n  // bad\n  function foo() {\n  ∙∙∙∙let name;\n  }\n\n  // bad\n  function bar() {\n  ∙let name;\n  }\n\n  // good\n  function baz() {\n  ∙∙let name;\n  }\n  ```\n\n- [19.2](#whitespace--before-blocks) <a id=\"whitespace--before-blocks\"></a> **【必须】** 在花括号前放置一个空格。 eslint: [`space-before-blocks`](https://eslint.org/docs/rules/space-before-blocks.html)\n\n  ```javascript\n  // bad\n  function test(){\n    console.log('test');\n  }\n\n  // good\n  function test() {\n    console.log('test');\n  }\n\n  // bad\n  dog.set('attr',{\n    age: '1 year',\n    breed: 'Bernese Mountain Dog',\n  });\n\n  // good\n  dog.set('attr', {\n    age: '1 year',\n    breed: 'Bernese Mountain Dog',\n  });\n  ```\n\n- [19.3](#whitespace--around-keywords) <a id=\"whitespace--around-keywords\"></a> **【必须】** 在控制语句中的左括号前放置1个空格（if，while等）。在函数调用和声明中，参数列表和函数名之间不能留空格。[`keyword-spacing`](https://eslint.org/docs/rules/keyword-spacing.html)\n\n  ```javascript\n  // bad\n  if(isJedi) {\n    fight ();\n  }\n\n  // good\n  if (isJedi) {\n    fight();\n  }\n\n  // bad\n  function fight () {\n    console.log ('Swooosh!');\n  }\n\n  // good\n  function fight() {\n    console.log('Swooosh!');\n  }\n  ```\n\n- [19.4](#whitespace--infix-ops) <a id=\"whitespace--infix-ops\"></a> **【必须】** 运算符左右设置各设置一个空格 eslint: [`space-infix-ops`](https://eslint.org/docs/rules/space-infix-ops.html)\n\n  ```javascript\n  // bad\n  const x=y+5;\n\n  // good\n  const x = y + 5;\n  ```\n\n- [19.5](#whitespace--newline-at-end) <a id=\"whitespace--newline-at-end\"></a> **【必须】** 在文件的结尾需要保留一个空行 eslint: [`eol-last`](https://github.com/eslint/eslint/blob/master/docs/rules/eol-last.md)\n\n  ```javascript\n  // bad\n  import { es6 } from './AirbnbStyleGuide';\n  // ...\n  export default es6;\n  ```\n\n  ```javascript\n  // bad\n  import { es6 } from './AirbnbStyleGuide';\n  // ...\n  export default es6;↵\n  ↵\n  ```\n\n  ```javascript\n  // good\n  import { es6 } from './AirbnbStyleGuide';\n  // ...\n  export default es6;↵\n  ```\n\n- [19.6](#whitespace--chains) <a id=\"whitespace--chains\"></a> **【推荐】** 在编写多个方法链式调用(超过两个方法链式调用)时。 使用前导点，强调这行是一个方法调用，而不是一个语句。\n  eslint: [`newline-per-chained-call`](https://eslint.org/docs/rules/newline-per-chained-call) [`no-whitespace-before-property`](https://eslint.org/docs/rules/no-whitespace-before-property)\n\n  ```javascript\n  // bad\n  $('#items').find('.selected').highlight().end().find('.open').updateCount();\n\n  // bad\n  $('#items').\n    find('.selected').\n      highlight().\n      end().\n    find('.open').\n      updateCount();\n\n  // good\n  $('#items')\n    .find('.selected')\n      .highlight()\n      .end()\n    .find('.open')\n      .updateCount();\n\n  // bad\n  const leds = stage.selectAll('.led').data(data).enter().append('svg:svg').classed('led', true)\n      .attr('width', (radius + margin) * 2).append('svg:g')\n      .attr('transform', `translate(${radius + margin},${radius + margin})`)\n      .call(tron.led);\n\n  // good\n  const leds = stage.selectAll('.led')\n      .data(data)\n    .enter().append('svg:svg')\n      .classed('led', true)\n      .attr('width', (radius + margin) * 2)\n    .append('svg:g')\n      .attr('transform', `translate(${radius + margin},${radius + margin})`)\n      .call(tron.led);\n\n  // good\n  const leds = stage.selectAll('.led').data(data);\n  ```\n\n- [19.7](#whitespace--after-blocks) <a id=\"whitespace--after-blocks\"></a> **【推荐】** 在块和下一个语句之前留下一空白行。\n\n  ```javascript\n  // bad\n  if (foo) {\n    return bar;\n  }\n  return baz;\n\n  // good\n  if (foo) {\n    return bar;\n  }\n\n  return baz;\n\n  // bad\n  const obj = {\n    foo() {\n    },\n    bar() {\n    },\n  };\n  return obj;\n\n  // good\n  const obj = {\n    foo() {\n    },\n\n    bar() {\n    },\n  };\n\n  return obj;\n\n  // bad\n  const arr = [\n    function foo() {\n    },\n    function bar() {\n    },\n  ];\n  return arr;\n\n  // good\n  const arr = [\n    function foo() {\n    },\n\n    function bar() {\n    },\n  ];\n\n  return arr;\n  ```\n\n- [19.8](#whitespace--padded-blocks) <a id=\"whitespace--padded-blocks\"></a> **【必须】** 不要在块的开头使用空白行。 eslint: [`padded-blocks`](https://eslint.org/docs/rules/padded-blocks.html)\n\n  ```javascript\n  // bad\n  function bar() {\n\n    console.log(foo);\n\n  }\n\n  // bad\n  if (baz) {\n\n    console.log(qux);\n  } else {\n    console.log(foo);\n\n  }\n\n  // bad\n  class Foo {\n\n    constructor(bar) {\n      this.bar = bar;\n    }\n  }\n\n  // good\n  function bar() {\n    console.log(foo);\n  }\n\n  // good\n  if (baz) {\n    console.log(qux);\n  } else {\n    console.log(foo);\n  }\n  ```\n\n- [19.9](#whitespace--no-multiple-blanks) <a id=\"whitespace--no-multiple-blanks\"></a> **【必须】** 不要使用多个空行填充代码。 eslint: [`no-multiple-empty-lines`](https://eslint.org/docs/rules/no-multiple-empty-lines)\n\n  <!-- markdownlint-disable MD012 -->\n  ```javascript\n  // bad\n  class Person {\n    constructor(fullName, email, birthday) {\n      this.fullName = fullName;\n\n\n      this.email = email;\n\n\n      this.setAge(birthday);\n    }\n\n\n    setAge(birthday) {\n      const today = new Date();\n\n\n      const age = this.getAge(today, birthday);\n\n\n      this.age = age;\n    }\n\n\n    getAge(today, birthday) {\n      // ..\n    }\n  }\n\n  // good\n  class Person {\n    constructor(fullName, email, birthday) {\n      this.fullName = fullName;\n      this.email = email;\n      this.setAge(birthday);\n    }\n\n    setAge(birthday) {\n      const today = new Date();\n      const age = getAge(today, birthday);\n      this.age = age;\n    }\n\n    getAge(today, birthday) {\n      // ..\n    }\n  }\n  ```\n\n- [19.10](#whitespace--in-parens) <a id=\"whitespace--in-parens\"></a> **【必须】** 不要在括号内添加空格。 eslint: [`space-in-parens`](https://eslint.org/docs/rules/space-in-parens.html)\n\n  ```javascript\n  // bad\n  function bar( foo ) {\n    return foo;\n  }\n\n  // good\n  function bar(foo) {\n    return foo;\n  }\n\n  // bad\n  if ( foo ) {\n    console.log(foo);\n  }\n\n  // good\n  if (foo) {\n    console.log(foo);\n  }\n  ```\n\n- [19.11](#whitespace--in-brackets) <a id=\"whitespace--in-brackets\"></a> **【必须】** 不要在中括号中添加空格。 eslint: [`array-bracket-spacing`](https://eslint.org/docs/rules/array-bracket-spacing.html)\n\n  ```javascript\n  // bad\n  const foo = [ 1, 2, 3 ];\n  console.log(foo[ 0 ]);\n\n  // good\n  const foo = [1, 2, 3];\n  console.log(foo[0]);\n  ```\n\n- [19.12](#whitespace--in-braces) <a id=\"whitespace--in-braces\"></a> **【推荐】** 在花括号内添加空格。 eslint: [`object-curly-spacing`](https://eslint.org/docs/rules/object-curly-spacing.html)\n\n  ```javascript\n  // bad\n  const foo = {clark: 'kent'};\n\n  // good\n  const foo = { clark: 'kent' };\n  ```\n\n- [19.13](#whitespace--max-len) <a id=\"whitespace--max-len\"></a> **【可选】** 避免让你的代码行超过120个字符(包括空格)。 注意：根据上边的[规则](#strings--line-length) <a id=\"strings--line-length\"></a>，长字符串编写可不受该规则约束，不应该被分解。 eslint: [`max-len`](https://eslint.org/docs/rules/max-len.html)\n\n  > 原因？ 这样能够提升代码可读性和可维护性。\n\n  ```javascript\n  // bad\n  const foo = jsonData && jsonData.foo && jsonData.foo.bar && jsonData.foo.bar.baz && jsonData.foo.bar.baz.quux && jsonData.foo.bar.baz.quux.xyzzy;\n\n  // bad\n  $.ajax({ method: 'POST', url: 'https://airbnb.com/', data: { name: 'John' } }).done(() => console.log('Congratulations!')).fail(() => console.log('You have failed this city.'));\n\n  // good\n  const foo = jsonData\n    && jsonData.foo\n    && jsonData.foo.bar\n    && jsonData.foo.bar.baz\n    && jsonData.foo.bar.baz.quux\n    && jsonData.foo.bar.baz.quux.xyzzy;\n\n  // better\n  const foo = jsonData\n    ?.foo\n    ?.bar\n    ?.baz\n    ?.quux\n    ?.xyzzy;\n\n  // good\n  $.ajax({\n    method: 'POST',\n    url: 'https://airbnb.com/',\n    data: { name: 'John' },\n  })\n    .done(() => console.log('Congratulations!'))\n    .fail(() => console.log('You have failed this city.'));\n  ```\n\n- [19.14](#whitespace--block-spacing) <a id=\"whitespace--block-spacing\"></a> **【必须】** 要求打开的块标志和同一行上的标志拥有一致的间距。此规则还会在同一行关闭的块标记和前边的标记强制实施一致的间距。 eslint: [`block-spacing`](https://eslint.org/docs/rules/block-spacing)\n\n  ```javascript\n  // bad\n  function foo() {return true;}\n  if (foo) { bar = 0;}\n\n  // good\n  function foo() { return true; }\n  if (foo) { bar = 0; }\n  ```\n\n- [19.15](#whitespace--comma-spacing) <a id=\"whitespace--comma-spacing\"></a> **【必须】** 逗号之前避免使用空格，逗号之后需要使用空格。eslint: [`comma-spacing`](https://eslint.org/docs/rules/comma-spacing)\n\n  ```javascript\n  // bad\n  const arr = [1 , 2];\n\n  // good\n  const arr = [1, 2];\n  ```\n\n- [19.16](#whitespace--computed-property-spacing) <a id=\"whitespace--computed-property-spacing\"></a> **【推荐】** 不要在计算","readmeFilename":"README.md","homepage":"https://git.woa.com/standards/javascript","repository":{"type":"git","url":"https://git.woa.com/standards/javascript.git"}}