{"id":13810929,"url":"https://github.com/Go7hic/front-end-best-practices","last_synced_at":"2025-05-14T15:31:22.238Z","repository":{"id":80345402,"uuid":"47347502","full_name":"Go7hic/front-end-best-practices","owner":"Go7hic","description":"一些前端的最佳实践，包括 HTML, CSS, JS ","archived":false,"fork":false,"pushed_at":"2020-05-01T13:29:55.000Z","size":33,"stargazers_count":101,"open_issues_count":0,"forks_count":13,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-08-04T03:01:53.781Z","etag":null,"topics":["best-practices","css","html","javascript"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Go7hic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-12-03T17:14:33.000Z","updated_at":"2024-08-04T03:02:02.932Z","dependencies_parsed_at":"2023-06-06T00:30:17.227Z","dependency_job_id":null,"html_url":"https://github.com/Go7hic/front-end-best-practices","commit_stats":null,"previous_names":["dyygtfx/front-end-best-practices"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Go7hic%2Ffront-end-best-practices","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Go7hic%2Ffront-end-best-practices/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Go7hic%2Ffront-end-best-practices/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Go7hic%2Ffront-end-best-practices/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Go7hic","download_url":"https://codeload.github.com/Go7hic/front-end-best-practices/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254171788,"owners_count":22026519,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["best-practices","css","html","javascript"],"created_at":"2024-08-04T03:00:32.422Z","updated_at":"2025-05-14T15:31:17.223Z","avatar_url":"https://github.com/Go7hic.png","language":null,"funding_links":[],"categories":["资源："],"sub_categories":[],"readme":"# front-end-best-practices\n一些前端的最佳实践，包括 html,css,javascript\n \n\n## HTML\n\n### 语义\n\nHTML5为我们提供大量的语义元素的目的就是为了准确地描述内容，确保你受益于其丰富的词汇。\n\n```html\n\u003c!-- bad --\u003e\n\u003cdiv id=\"main\"\u003e\n  \u003cdiv class=\"article\"\u003e\n    \u003cdiv class=\"header\"\u003e\n      \u003ch1\u003eBlog post\u003c/h1\u003e\n      \u003cp\u003ePublished: \u003cspan\u003e21st Feb, 2015\u003c/span\u003e\u003c/p\u003e\n    \u003c/div\u003e\n    \u003cp\u003e…\u003c/p\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n\n\u003c!-- good --\u003e\n\u003cmain\u003e\n  \u003carticle\u003e\n    \u003cheader\u003e\n      \u003ch1\u003eBlog post\u003c/h1\u003e\n      \u003cp\u003ePublished: \u003ctime datetime=\"2015-02-21\"\u003e21st Feb, 2015\u003c/time\u003e\u003c/p\u003e\n    \u003c/header\u003e\n    \u003cp\u003e…\u003c/p\u003e\n  \u003c/article\u003e\n\u003c/main\u003e\n```\n\n确保你了解你使用的语义元素。错误的使用语义元素是很糟糕的。\n\n```html\n\u003c!-- bad --\u003e\n\u003ch1\u003e\n  \u003cfigure\u003e\n    \u003cimg alt=Company src=logo.png\u003e\n  \u003c/figure\u003e\n\u003c/h1\u003e\n\n\u003c!-- good --\u003e\n\u003ch1\u003e\n  \u003cimg alt=Company src=logo.png\u003e\n\u003c/h1\u003e\n```\n\n### 简洁\n\n保持代码简洁。忘记你的旧 XHTM L的习惯。\n\n```html\n\u003c!-- bad --\u003e\n\u003c!doctype html\u003e\n\u003chtml lang=en\u003e\n  \u003chead\u003e\n    \u003cmeta http-equiv=Content-Type content=\"text/html; charset=utf-8\" /\u003e\n    \u003ctitle\u003eContact\u003c/title\u003e\n    \u003clink rel=stylesheet href=style.css type=text/css /\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003ch1\u003eContact me\u003c/h1\u003e\n    \u003clabel\u003e\n      Email address:\n      \u003cinput type=email placeholder=you@email.com required=required /\u003e\n    \u003c/label\u003e\n    \u003cscript src=main.js type=text/javascript\u003e\u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n\n\u003c!-- good --\u003e\n\u003c!doctype html\u003e\n\u003chtml lang=en\u003e\n  \u003cmeta charset=utf-8\u003e\n  \u003ctitle\u003eContact\u003c/title\u003e\n  \u003clink rel=stylesheet href=style.css\u003e\n\n  \u003ch1\u003eContact me\u003c/h1\u003e\n  \u003clabel\u003e\n    Email address:\n    \u003cinput type=email placeholder=you@email.com required\u003e\n  \u003c/label\u003e\n  \u003cscript src=main.js\u003e\u003c/script\u003e\n\u003c/html\u003e\n```\n\n### 可访问性\n\n可访问性不应该是后面再来做的事。但你也不必成为一个WCAG专家来提高你的\n网站,你可以立即做一些小事情,就会有巨大的改变,如:\n- 学习正确使用“alt”属性\n- 确保你的链接和按钮等标记(没有`“\u003c div class = button”`这种滥用)\n- 不完全依赖颜色信息交流\n- 明确 `label` `input`控件\n\n```html\n\u003c!-- bad --\u003e\n\u003ch1\u003e\u003cimg alt=\"Logo\" src=\"logo.png\"\u003e\u003c/h1\u003e\n\n\u003c!-- good --\u003e\n\u003ch1\u003e\u003cimg alt=\"My Company, Inc.\" src=\"logo.png\"\u003e\u003c/h1\u003e\n```\n\n### 语言和字符编码\n语言虽然是可选的，但还是推荐在根元素上声明它。\n\nHTML标准要求页面使用UTF-8字符编码。必须声明它，虽然可以在Content-Type HTTP头文件中声明它，但建议始终在文档级别声明它。\n\n```html\n\u003c!-- bad --\u003e\n\u003c!doctype html\u003e\n\u003ctitle\u003eHello, world.\u003c/title\u003e\n\n\u003c!-- good --\u003e\n\u003c!doctype html\u003e\n\u003chtml lang=en\u003e\n  \u003cmeta charset=utf-8\u003e\n  \u003ctitle\u003eHello, world.\u003c/title\u003e\n\u003c/html\u003e\n```\n\n### 性能\n\n除非有一个充分的理由不然在加载脚本内容之前不要阻止呈现的页面。\n\n```html\n\u003c!-- bad --\u003e\n\u003c!doctype html\u003e\n\u003cmeta charset=utf-8\u003e\n\u003cscript src=analytics.js\u003e\u003c/script\u003e\n\u003ctitle\u003eHello, world.\u003c/title\u003e\n\u003cp\u003e...\u003c/p\u003e\n\n\u003c!-- good --\u003e\n\u003c!doctype html\u003e\n\u003cmeta charset=utf-8\u003e\n\u003ctitle\u003eHello, world.\u003c/title\u003e\n\u003cp\u003e...\u003c/p\u003e\n\u003cscript src=analytics.js\u003e\u003c/script\u003e\n```\n\n## CSS\n\n### 分号\n\n分号在技术上是一个分离器,总是把它当作结束符。\n\n```css\n/* bad */\ndiv {\n  color: red\n}\n\n/* good */\ndiv {\n  color: red;\n}\n```\n\n### 盒模型\n\n盒子模型应该为整个文档是一样的。一个全局\n“* { box-sizing:border-box;}”是可以的,在特定的元素里如果能避免最好不要改变它默认的盒模型。\n\n```css\n/* bad */\ndiv {\n  width: 100%;\n  padding: 10px;\n  box-sizing: border-box;\n}\n\n/* good */\ndiv {\n  padding: 10px;\n}\n```\n\n### 文档流\n\n如果你能避免最好不要改变一个元素的默认行为。尽可能的保持元素\n自然文档流。例如,删除图像下的 white-space 不应该让你改变其默认显示:\n\n```css\n/* bad */\nimg {\n  display: block;\n}\n\n/* good */\nimg {\n  vertical-align: middle;\n}\n```\n\n同样的,如果你能避免最好不要把一个元素脱离文档流。\n\n```css\n/* bad */\ndiv {\n  width: 100px;\n  position: absolute;\n  right: 0;\n}\n\n/* good */\ndiv {\n  width: 100px;\n  margin-left: auto;\n}\n```\n\n### 定位\n\ncss有很多方法来定位元素，但是最好使用下面的属性/值，按照优先顺序:\n\n```\ndisplay: flex;\ndisplay: grid;\ndisplay: block;\nposition: relative;\nposition: sticky;\nposition: absolute;\nposition: fixed;\n```\n应该尽量避免从常规文档流中删除元素，例如，使用position：absolute。\n\n### 选择器\n\n减少选择器紧密耦合的DOM。考虑添加一个类的元素，当你超过 3 层结构可以用伪类选择器匹配,或后代\n兄弟选择器组合。\n\n```css\n/* bad */\ndiv:first-of-type :last-child \u003e p ~ *\n\n/* good */\ndiv:first-of-type .info\n```\n\n避免重载你的选择器在你不需要的时候。\n\n```css\n/* bad */\nimg[src$=svg], ul \u003e li:first-child {\n  opacity: 0;\n}\n\n/* good */\n[src$=svg], ul \u003e :first-child {\n  opacity: 0;\n}\n```\n\n### 特殊点\n\n不要让值和选择器难以覆盖。减少使用id和\n避免`!important`。\n```css\n/* bad */\n.bar {\n  color: green !important;\n}\n.foo {\n  color: red;\n}\n\n/* good */\n.foo.bar {\n  color: green;\n}\n.foo {\n  color: red;\n}\n```\n\n### override\n\noverride 的样式让选择器和调试困难。尽可能的避免它。\n```css\n/* bad */\nli {\n  visibility: hidden;\n}\nli:first-child {\n  visibility: visible;\n}\n\n/* good */\nli + li {\n  visibility: hidden;\n}\n```\n\n### 继承\n\n不要重复声明样式,是可以继承的。\n\n```css\n/* bad */\ndiv h1, div p {\n  text-shadow: 0 1px 0 #fff;\n}\n\n/* good */\ndiv {\n  text-shadow: 0 1px 0 #fff;\n}\n```\n\n### 简洁\n\n保持代码简洁。尽可能的使用简写属性,避免使用多个属性。\n\n\n```css\n/* bad */\ndiv {\n  transition: all 1s;\n  top: 50%;\n  margin-top: -10px;\n  padding-top: 5px;\n  padding-right: 10px;\n  padding-bottom: 20px;\n  padding-left: 10px;\n}\n\n/* good */\ndiv {\n  transition: 1s;\n  top: calc(50% - 10px);\n  padding: 5px 10px 20px;\n}\n```\n\n### 语言编码\n\n只能是英语和数字\n\n```css\n/* bad */\n:nth-child(2n + 1) {\n  transform: rotate(360deg);\n}\n\n/* good */\n:nth-child(odd) {\n  transform: rotate(1turn);\n}\n```\n\n### 前缀\n\n积极除掉过时的前缀。如果你需要使用它们,插入他们的标准属性之前\n\n```css\n/* bad */\ndiv {\n  transform: scale(2);\n  -webkit-transform: scale(2);\n  -moz-transform: scale(2);\n  -ms-transform: scale(2);\n  transition: 1s;\n  -webkit-transition: 1s;\n  -moz-transition: 1s;\n  -ms-transition: 1s;\n}\n\n/* good */\ndiv {\n  -webkit-transform: scale(2);\n  transform: scale(2);\n  transition: 1s;\n}\n```\n\n### 动画\n用 transitions 代替  animations。动画执行的时候尽量避免使用其他属性，除了 `opacity` 和 `transform`.\n\n```css\n/* bad */\ndiv:hover {\n  animation: move 1s forwards;\n}\n@keyframes move {\n  100% {\n    margin-left: 100px;\n  }\n}\n\n/* good */\ndiv:hover {\n  transition: 1s;\n  transform: translateX(100px);\n}\n```\n\n### 单位\n\n这个具体看场景，当你使用相对单位的时候推荐使用`rem`。用 秒 代替 毫秒\n\n```css\n/* bad */\ndiv {\n  margin: 0px;\n  font-size: .9em;\n  line-height: 22px;\n  transition: 500ms;\n}\n\n/* good */\ndiv {\n  margin: 0;\n  font-size: .9rem;\n  line-height: 1.5;\n  transition: .5s;\n}\n```\n\n### 颜色\n\n如果你需要使用透明，使用 `rgba`。否则，使用 16 进制格式的\n```css\n/* bad */\ndiv {\n  color: hsl(103, 54%, 43%);\n}\n\n/* good */\ndiv {\n  color: #5a3;\n}\n```\n\n### 图片\n\n如果能用 css 代替最好避免使用 HTTP 请求\n\n```css\n/* bad */\ndiv::before {\n  content: url(white-circle.svg);\n}\n\n/* good */\ndiv::before {\n  content: \"\";\n  display: block;\n  width: 20px;\n  height: 20px;\n  border-radius: 50%;\n  background: #fff;\n}\n```\n\n### Hacks\n\n不要使用这些\n\n```css\n/* bad */\ndiv {\n  // position: relative;\n  transform: translateZ(0);\n}\n\n/* good */\ndiv {\n  /* position: relative; */\n  will-change: transform;\n}\n```\n\n## JavaScript\n\n### 性能\n\n代码的可读性，正确性，可表达性优于性能。JavaScript 基本上不会有性能上的瓶颈。需要优化的东西像 图片优化，网络请求优化，DOM 渲染优化。如果你要在这个文档记住一条，那就记住这个吧。\n\n```javascript\n// bad (albeit way faster)\nconst arr = [1, 2, 3, 4];\nconst len = arr.length;\nvar i = -1;\nvar result = [];\nwhile (++i \u003c len) {\n  var n = arr[i];\n  if (n % 2 \u003e 0) continue;\n  result.push(n * n);\n}\n\n// good\nconst arr = [1, 2, 3, 4];\nconst isEven = n =\u003e n % 2 == 0;\nconst square = n =\u003e n * n;\n\nconst result = arr.filter(isEven).map(square);\n```\n\n### 无状态\n\n尽量让你的函数保持干净，所有的函数最好没有副作用，不要使用外部数据，返回一个新的对象代替现在已经存在的。\n\n```javascript\n// bad\nconst merge = (target, ...sources) =\u003e Object.assign(target, ...sources);\nmerge({ foo: \"foo\" }, { bar: \"bar\" }); // =\u003e { foo: \"foo\", bar: \"bar\" }\n\n// good\nconst merge = (...sources) =\u003e Object.assign({}, ...sources);\nmerge({ foo: \"foo\" }, { bar: \"bar\" }); // =\u003e { foo: \"foo\", bar: \"bar\" }\n```\n\n### 原生方法\n尽可能的使用语言自带的方法\n\n```javascript\n// bad\nconst toArray = obj =\u003e [].slice.call(obj);\n\n// good\nconst toArray = (() =\u003e\n  Array.from ? Array.from : obj =\u003e [].slice.call(obj)\n)();\n```\n\n### 类型转换（隐式转换）\n\n请放心使用类型隐式转换当那样做有意义的时候，虽然说是要避免使用它，但是也不要盲目相信权威。\n\n```javascript\n// bad\nif (x === undefined || x === null) { ... }\n\n// good\nif (x == undefined) { ... }\n```\n\n### 循环\n\n当你不得已使用可变的对象时最好不要使用循环，使用`array.prototype`的方法。\n\n```javascript\n// bad\nconst sum = arr =\u003e {\n  var sum = 0;\n  var i = -1;\n  for (;arr[++i];) {\n    sum += arr[i];\n  }\n  return sum;\n};\nsum([1, 2, 3]); // =\u003e 6\n\n// good\nconst sum = arr =\u003e\n  arr.reduce((x, y) =\u003e x + y);\n\nsum([1, 2, 3]); // =\u003e 6\n```\n\n如果你不想，或者说使用 `array.prototype`方法很恶心，建议使用递归\n\n```javascript\n// bad\nconst createDivs = howMany =\u003e {\n  while (howMany--) {\n    document.body.insertAdjacentHTML(\"beforeend\", \"\u003cdiv\u003e\u003c/div\u003e\");\n  }\n};\ncreateDivs(5);\n\n// bad\nconst createDivs = howMany =\u003e\n  [...Array(howMany)].forEach(() =\u003e\n    document.body.insertAdjacentHTML(\"beforeend\", \"\u003cdiv\u003e\u003c/div\u003e\")\n  );\ncreateDivs(5);\n\n// good\nconst createDivs = howMany =\u003e {\n  if (!howMany) return;\n  document.body.insertAdjacentHTML(\"beforeend\", \"\u003cdiv\u003e\u003c/div\u003e\");\n  return createDivs(howMany - 1);\n};\ncreateDivs(5);\n```\n这是一个通用的[循环函数]((https://gist.github.com/bendc/6cb2db4a44ec30208e86))，让递归更简单\n\n### Arguments\n\n忘了  `arguments` 对象。其他的参数是个更好的选择，因为：\n1. 可以命名，能够让你有个更符合函数期待的参数\n2. 和数组没啥大区别，可以让你更方便的使用\n\n\n```javascript\n// bad\nconst sortNumbers = () =\u003e\n  Array.prototype.slice.call(arguments).sort();\n\n// good\nconst sortNumbers = (...numbers) =\u003e numbers.sort();\n```\n\n### Apply\n\n忘了 `apply()`吧， 使用操作符代替.\n\n```javascript\nconst greet = (first, last) =\u003e `Hi ${first} ${last}`;\nconst person = [\"John\", \"Doe\"];\n\n// bad\ngreet.apply(null, person);\n\n// good\ngreet(...person);\n```\n\n### Bind\n\n当有更常用的办法时不要用 `bind()`\n\n```javascript\n// bad\n[\"foo\", \"bar\"].forEach(func.bind(this));\n\n// good\n[\"foo\", \"bar\"].forEach(func, this);\n```\n```javascript\n// bad\nconst person = {\n  first: \"John\",\n  last: \"Doe\",\n  greet() {\n    const full = function() {\n      return `${this.first} ${this.last}`;\n    }.bind(this);\n    return `Hello ${full()}`;\n  }\n}\n\n// good\nconst person = {\n  first: \"John\",\n  last: \"Doe\",\n  greet() {\n    const full = () =\u003e `${this.first} ${this.last}`;\n    return `Hello ${full()}`;\n  }\n}\n```\n\n### 高阶函数\n\n当你没必要的时候避免使用嵌套函数\n\n```javascript\n// bad\n[1, 2, 3].map(num =\u003e String(num));\n\n// good\n[1, 2, 3].map(String);\n```\n\n### 组合\n\n避免多个函数的嵌套，使用组合代替\n\n```javascript\nconst plus1 = a =\u003e a + 1;\nconst mult2 = a =\u003e a * 2;\n\n// bad\nmult2(plus1(5)); // =\u003e 12\n\n// good\nconst pipeline = (...funcs) =\u003e val =\u003e funcs.reduce((a, b) =\u003e b(a), val);\nconst addThenMult = pipeline(plus1, mult2);\naddThenMult(5); // =\u003e 12\n```\n\n### 缓存\n\n```javascript\n// bad\nconst contains = (arr, value) =\u003e\n  Array.prototype.includes\n    ? arr.includes(value)\n    : arr.some(el =\u003e el === value);\ncontains([\"foo\", \"bar\"], \"baz\"); // =\u003e false\n\n// good\nconst contains = (() =\u003e\n  Array.prototype.includes\n    ? (arr, value) =\u003e arr.includes(value)\n    : (arr, value) =\u003e arr.some(el =\u003e el === value)\n)();\ncontains([\"foo\", \"bar\"], \"baz\"); // =\u003e false\n```\n\n### 变量\n\n建议使用 `const` 代替 `let`,`let` 代替 `var`。\n\n```javascript\n// bad\nvar me = new Map();\nme.set(\"name\", \"Ben\").set(\"country\", \"Belgium\");\n\n// good\nconst me = new Map();\nme.set(\"name\", \"Ben\").set(\"country\", \"Belgium\");\n```\n\n### 条件\n\n建议用 匿名执行函数返回语句 代替 if,else,switch 语句。\n```javascript\n// bad\nvar grade;\nif (result \u003c 50)\n  grade = \"bad\";\nelse if (result \u003c 90)\n  grade = \"good\";\nelse\n  grade = \"excellent\";\n\n// good\nconst grade = (() =\u003e {\n  if (result \u003c 50)\n    return \"bad\";\n  if (result \u003c 90)\n    return \"good\";\n  return \"excellent\";\n})();\n```\n\n### 对象迭代\n\n尽可能的避免使用 `for .. in`\n\n```javascript\nconst shared = { foo: \"foo\" };\nconst obj = Object.create(shared, {\n  bar: {\n    value: \"bar\",\n    enumerable: true\n  }\n});\n\n// bad\nfor (var prop in obj) {\n  if (obj.hasOwnProperty(prop))\n    console.log(prop);\n}\n\n// good\nObject.keys(obj).forEach(prop =\u003e console.log(prop));\n```\n\n### 使用 Map 创建对象\n\n在使用对象的时候，Map 是个更好的选择\n\n```javascript\n// bad\nconst me = {\n  name: \"Ben\",\n  age: 30\n};\nvar meSize = Object.keys(me).length;\nmeSize; // =\u003e 2\nme.country = \"Belgium\";\nmeSize++;\nmeSize; // =\u003e 3\n\n// good\nconst me = new Map();\nme.set(\"name\", \"Ben\");\nme.set(\"age\", 30);\nme.size; // =\u003e 2\nme.set(\"country\", \"Belgium\");\nme.size; // =\u003e 3\n```\n\n### 柯里化\n\n柯里化很强大，但是很多开发者不是很熟悉。不要滥用它，但适当的使用是很不错的。\n\n```javascript\n// bad\nconst sum = a =\u003e b =\u003e a + b;\nsum(5)(3); // =\u003e 8\n\n// good\nconst sum = (a, b) =\u003e a + b;\nsum(5, 3); // =\u003e 8\n```\n\n### 可读性\n\n不要用一些看似聪明的小技巧混淆代码的可读性\n\n```javascript\n// bad\nfoo || doSomething();\n\n// good\nif (!foo) doSomething();\n```\n```javascript\n// bad\nvoid function() { /* IIFE */ }();\n\n// good\n(function() { /* IIFE */ }());\n```\n```javascript\n// bad\nconst n = ~~3.14;\n\n// good\nconst n = Math.floor(3.14);\n```\n\n### 代码复用\n\n不要害怕创造许多小的，高度组合可重复使用的函数\n\n```javascript\n// bad\narr[arr.length - 1];\n\n// good\nconst first = arr =\u003e arr[0];\nconst last = arr =\u003e first(arr.slice(-1));\nlast(arr);\n```\n```javascript\n// bad\nconst product = (a, b) =\u003e a * b;\nconst triple = n =\u003e n * 3;\n\n// good\nconst product = (a, b) =\u003e a * b;\nconst triple = product.bind(null, 3);\n```\n\n### 依赖\n\n减少依赖，你不熟悉第三方代码，不要为了一个简单的方法加载一个库。\n\n```javascript\n// bad\nvar _ = require(\"underscore\");\n_.compact([\"foo\", 0]));\n_.unique([\"foo\", \"foo\"]);\n_.union([\"foo\"], [\"bar\"], [\"foo\"]);\n\n// good\nconst compact = arr =\u003e arr.filter(el =\u003e el);\nconst unique = arr =\u003e [...Set(arr)];\nconst union = (...arr) =\u003e unique([].concat(...arr));\n\ncompact([\"foo\", 0]);\nunique([\"foo\", \"foo\"]);\nunion([\"foo\"], [\"bar\"], [\"foo\"]);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FGo7hic%2Ffront-end-best-practices","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FGo7hic%2Ffront-end-best-practices","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FGo7hic%2Ffront-end-best-practices/lists"}