blog-hexo/public/2023/11/06/clqko8ns3000qobz37t4gdxfw/index.html
2023-12-25 16:43:49 +08:00

1641 lines
270 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
码场悟道
</title>
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="author" content="Mozzie">
<link rel="canonical" href="https://mozzie.cn/2023/11/06/clqko8ns3000qobz37t4gdxfw/">
<link rel="icon" type="image/svg" href='data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 7h1a2 2 0 0 1 2 2v.5a.5.5 0 0 0 .5.5a.5.5 0 0 1 .5.5v3a.5.5 0 0 1-.5.5a.5.5 0 0 0-.5.5v.5a2 2 0 0 1-2 2h-2"></path><path d="M8 7H6a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h1"></path><path d="M12 8l-2 4h3l-2 4"></path></g></svg>'>
<link rel="stylesheet" href="/css/7265f98e.css">
<script>window.i18n = {"tip-status-done":"完成","tip-status-default":"全部","tip-status-todo":"计划","tip-status-doing":"进行","tip-status-other":"其他","text-select":"选择","text-move":"移动","text-esc":"退出","January":"一月","February":"二月","March":"三月","April":"四月","May":"五月","June":"六月","July":"七月","August":"八月","September":"九月","October":"十月","November":"十一月","December":"十二月"}</script>
<meta name="generator" content="Hexo 7.0.0"></head>
<body id="app">
<aside id="aside-box" class="left-aside">
<div class="header">
<link rel="stylesheet" href="/css/61875ce9.css">
<div class="profile">
<a class="badge" href="/">
<span>Hi</span>
<span>Mozzie</span>
</a>
<cosy-tooltip id="left-aside-button" placement="right">
<span slot="content">
<span>显示 / 隐藏 左侧导航</span>
<cosy-short-key>[</cosy-short-key>
</span>
<cosy-icon>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20">
<g fill="none">
<path d="M16 4c1.104-.019 2 .896 2 2v8a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h12zm1 2a1 1 0 0 0-1-1h-2.995v10H16a1 1 0 0 0 1-1V6zm-4.995 9V5H4.001a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h8.004z" fill="currentColor"></path>
</g>
</svg>
</cosy-icon>
</cosy-tooltip>
</div>
<script src="/js/a66044b6.js"></script>
<cosy-search id="post-search" placeholder="搜索">
<div slot="short-key">
<cosy-short-key></cosy-short-key>
<cosy-short-key>K</cosy-short-key>
</div>
</cosy-search>
<script>
window.algolia = {
appId: "5DTW808BZ8",
SearchOnlyAPIKey: "27845b245efc8a2853cc0bdc7366ea26"
}
</script>
<script src="/js/5f00f278.js"></script>
</div>
<div class="aside-category">
<link rel="stylesheet" href="/css/db04a759.css">
<nav class="category-nav cosy-scrollbar">
<ul><li data-path="archives">
<a href="/archives">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20"><g fill="none"><path d="M3.5 3A1.5 1.5 0 0 0 2 4.5v4A1.5 1.5 0 0 0 3.5 10h9A1.5 1.5 0 0 0 14 8.5v-4A1.5 1.5 0 0 0 12.5 3h-9zM3 4.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-.5.5h-9a.5.5 0 0 1-.5-.5v-4zm.5 6.5A1.5 1.5 0 0 0 2 12.5v4A1.5 1.5 0 0 0 3.5 18h9a1.5 1.5 0 0 0 1.5-1.5v-4a1.5 1.5 0 0 0-1.5-1.5h-9zM3 12.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-.5.5h-9a.5.5 0 0 1-.5-.5v-4zm14-.063a2.003 2.003 0 0 1-2.5-1.937A2 2 0 0 1 16 8.563a2.005 2.005 0 0 1 1 0a2 2 0 0 1 0 3.874zM16.5 3a.5.5 0 0 1 .5.5v4.041a3.02 3.02 0 0 0-1 0V3.5a.5.5 0 0 1 .5-.5zm0 10.5c-.17 0-.337-.014-.5-.041V17.5a.5.5 0 0 0 1 0v-4.041c-.163.027-.33.041-.5.041z" fill="currentColor"></path></g></svg>
<div class="ellipsis">归档</div>
</a>
</li><li data-path="cosy-roadmap">
<a href="/cosy-roadmap">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20"><g fill="none"><path d="M9.384 2a1 1 0 0 0-.966.742L4.616 17H2.5a.5.5 0 0 0 0 1h15a.5.5 0 0 0 0-1h-2.116L11.582 2.742A1 1 0 0 0 10.616 2H9.384zM5.651 17l.8-3H11.5a.5.5 0 0 0 0-1H6.717l.534-2H10.5a.5.5 0 0 0 0-1H7.517l1.867-7h1.232l3.733 14H5.651z" fill="currentColor"></path></g></svg>
<div class="ellipsis">路线图</div>
</a>
</li><li data-path="cosy-resume">
<a href="/cosy-resume">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20"><g fill="none"><path d="M8.5 4.498a1.5 1.5 0 1 1 3 0a1.5 1.5 0 0 1-3 0zm1.5-2.5a2.5 2.5 0 0 0-2.43 3.086L5.471 4.15a1.761 1.761 0 0 0-2.317.88c-.4.882-.008 1.917.877 2.31L7 8.662v2.287l-1.877 4.645a1.75 1.75 0 0 0 3.245 1.311l1.556-3.849a.073.073 0 0 1 .028-.038a.086.086 0 0 1 .046-.012c.02 0 .035.005.046.012a.074.074 0 0 1 .028.038l1.555 3.849a1.75 1.75 0 0 0 3.245-1.311L13 10.96V8.662l2.968-1.322a1.74 1.74 0 0 0 .877-2.31a1.761 1.761 0 0 0-2.317-.88l-2.097.934a2.5 2.5 0 0 0-2.43-3.086zM4.065 5.444a.761.761 0 0 1 1-.38l3.918 1.744a2.5 2.5 0 0 0 2.034 0l3.918-1.744a.761.761 0 0 1 1 .38a.739.739 0 0 1-.373.983l-2.969 1.321a1 1 0 0 0-.593.914v2.298a1 1 0 0 0 .073.375l1.872 4.633a.75.75 0 0 1-1.39.562l-1.556-3.849c-.364-.9-1.639-.9-2.003 0l-1.555 3.85a.75.75 0 1 1-1.39-.562l1.876-4.646A1 1 0 0 0 8 10.95V8.662a1 1 0 0 0-.593-.914L4.438 6.427a.739.739 0 0 1-.373-.983z" fill="currentColor"></path></g></svg>
<div class="ellipsis">简历</div>
</a>
</li></ul>
<ul><li class="">
<a href="/categories/EQ/">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5.636 5.636a9 9 0 0 1 13.397.747L13.414 12l5.619 5.617A9 9 0 1 1 5.636 5.636z"></path><circle cx="11.5" cy="7.5" r="1" fill="currentColor"></circle></g></svg>
<div class="ellipsis">
<span>EQ</span>
</div>
</a>
</li><li class="">
<a href="/categories/Finance/">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"></circle><path d="M14.8 9A2 2 0 0 0 13 8h-2a2 2 0 0 0 0 4h2a2 2 0 0 1 0 4h-2a2 2 0 0 1-1.8-1"></path><path d="M12 6v2m0 8v2"></path></g></svg>
<div class="ellipsis">
<span>Finance</span>
</div>
</a>
</li><li class="active">
<a href="/categories/Front-End/">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 4l-2 14.5l-6 2l-6-2L4 4z"></path><path d="M7.5 8h3v8l-2-1"></path><path d="M16.5 8H14a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h1.423a.5.5 0 0 1 .495.57L15.5 15.5l-2 .5"></path></g></svg>
<div class="ellipsis">
<span>Front-End</span>
</div>
</a>
</li><li class="">
<a href="/categories/Hexo/">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 17v1a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-1"></path><path d="M8 16h8"></path><path d="M8.322 12.582l7.956.836"></path><path d="M8.787 9.168l7.826 1.664"></path><path d="M10.096 5.764l7.608 2.472"></path></g></svg>
<div class="ellipsis">
<span>Hexo</span>
</div>
</a>
</li><li class="">
<a href="/categories/%E6%B1%82%E5%AD%A6%E4%B9%8B%E8%B7%AF/">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 4a2 2 0 0 0-2 2v3a2 3 0 0 1-2 3a2 3 0 0 1 2 3v3a2 2 0 0 0 2 2"></path><path d="M17 4a2 2 0 0 1 2 2v3a2 3 0 0 0 2 3a2 3 0 0 0-2 3v3a2 2 0 0 1-2 2"></path></g></svg>
<div class="ellipsis">
<span>求学之路</span>
</div>
</a>
</li><li class="">
<a href="/categories/%E8%87%AA%E5%AA%92%E4%BD%93/">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><path d="M9 12a4 4 0 1 0 4 4V4a5 5 0 0 0 5 5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg>
<div class="ellipsis">
<span>自媒体</span>
</div>
</a>
</li></ul>
</nav>
<script src="/js/118098c2.js"></script>
</div>
<div class="bottom">
<cosy-tooltip id="button-preference" placement="right">
<span slot="content">
<span>偏好</span>
<cosy-short-key></cosy-short-key>
<cosy-short-key>p</cosy-short-key>
</span>
<cosy-icon bordered id="button-about-cosy-theme">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16">
<g fill="none">
<path d="M8 6a2 2 0 1 0 0 4a2 2 0 0 0 0-4zM7 8a1 1 0 1 1 2 0a1 1 0 0 1-2 0zm3.618-3.602a.708.708 0 0 1-.824-.567l-.26-1.416a.354.354 0 0 0-.275-.282a6.072 6.072 0 0 0-2.519 0a.354.354 0 0 0-.275.282l-.259 1.416a.71.71 0 0 1-.936.538l-1.359-.484a.355.355 0 0 0-.382.095c-.569.627-1 1.367-1.262 2.173a.352.352 0 0 0 .108.378l1.102.931a.704.704 0 0 1 0 1.076l-1.102.931a.352.352 0 0 0-.108.378A5.986 5.986 0 0 0 3.53 12.02a.355.355 0 0 0 .382.095l1.36-.484a.708.708 0 0 1 .936.538l.258 1.416c.026.14.135.252.275.281a6.075 6.075 0 0 0 2.52 0a.353.353 0 0 0 .274-.281l.26-1.416a.71.71 0 0 1 .936-.538l1.359.484c.135.048.286.01.382-.095c.569-.627 1-1.367 1.262-2.173a.352.352 0 0 0-.108-.378l-1.102-.931a.703.703 0 0 1 0-1.076l1.102-.931a.352.352 0 0 0 .108-.378A5.985 5.985 0 0 0 12.47 3.98a.355.355 0 0 0-.382-.095l-1.36.484a.71.71 0 0 1-.111.03zm-6.62.58l.937.333a1.71 1.71 0 0 0 2.255-1.3l.177-.97a5.105 5.105 0 0 1 1.265 0l.178.97a1.708 1.708 0 0 0 2.255 1.3L12 4.977c.255.334.467.698.63 1.084l-.754.637a1.704 1.704 0 0 0 0 2.604l.755.637a4.99 4.99 0 0 1-.63 1.084l-.937-.334a1.71 1.71 0 0 0-2.255 1.3l-.178.97a5.099 5.099 0 0 1-1.265 0l-.177-.97a1.708 1.708 0 0 0-2.255-1.3L4 11.023a4.987 4.987 0 0 1-.63-1.084l.754-.638a1.704 1.704 0 0 0 0-2.603l-.755-.637c.164-.386.376-.75.63-1.084z" fill="currentColor"></path>
</g>
</svg>
</cosy-icon>
</cosy-tooltip>
</div>
</aside>
<main>
<link rel="stylesheet" href="/css/9fa090c7.css">
<div class="post-container">
<header>
<div class="left">
<link rel="stylesheet" href="/css/7d333f9e.css">
<nav class="breadcrumb">
<section>
<cosy-tooltip placement="bottom-left">
<span slot="content"><span>首页</span>
<cosy-short-key></cosy-short-key>
<cosy-short-key>H</cosy-short-key>
</span>
<cosy-icon href="/">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20">
<g fill="none">
<path d="M8.998 2.388a1.5 1.5 0 0 1 2.005 0l5.5 4.942A1.5 1.5 0 0 1 17 8.445V15.5a1.5 1.5 0 0 1-1.5 1.5H13a1.5 1.5 0 0 1-1.5-1.5V12a.5.5 0 0 0-.5-.5H9a.5.5 0 0 0-.5.5v3.5A1.5 1.5 0 0 1 7 17H4.5A1.5 1.5 0 0 1 3 15.5V8.445c0-.425.18-.83.498-1.115l5.5-4.942zm1.336.744a.5.5 0 0 0-.668 0l-5.5 4.942A.5.5 0 0 0 4 8.445V15.5a.5.5 0 0 0 .5.5H7a.5.5 0 0 0 .5-.5V12A1.5 1.5 0 0 1 9 10.5h2a1.5 1.5 0 0 1 1.5 1.5v3.5a.5.5 0 0 0 .5.5h2.5a.5.5 0 0 0 .5-.5V8.445a.5.5 0 0 0-.166-.371l-5.5-4.942z" fill="currentColor"></path>
</g>
</svg>
</cosy-icon>
</cosy-tooltip>
<svg class="arrow" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20">
<g fill="none">
<path d="M7.733 4.207a.75.75 0 0 1 1.06.026l5.001 5.25a.75.75 0 0 1 0 1.035l-5 5.25a.75.75 0 1 1-1.087-1.034L12.216 10l-4.51-4.734a.75.75 0 0 1 .027-1.06z" fill="currentColor"></path>
</g>
</svg>
<a class="ellipsis" href="/categories/Front-End/">
Front-End
</a>
<svg class="arrow" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20">
<g fill="none">
<path d="M7.733 4.207a.75.75 0 0 1 1.06.026l5.001 5.25a.75.75 0 0 1 0 1.035l-5 5.25a.75.75 0 1 1-1.087-1.034L12.216 10l-4.51-4.734a.75.75 0 0 1 .027-1.06z" fill="currentColor"></path>
</g>
</svg>
<span class="ellipsis">
码场悟道
</span>
</section>
</nav>
<script src="/js/31d6cfe0.js"></script>
</div>
<div class="right">
<cosy-tooltip id="toc-show-button" placement="left">
<span slot="content">
<span>显示 / 隐藏 文章目录</span>
<cosy-short-key>]</cosy-short-key>
</span>
<cosy-icon>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20">
<g fill="none">
<path d="M4 4c-1.104-.019-2 .896-2 2v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2H4zM3 6a1 1 0 0 1 1-1h2.995v10H4a1 1 0 0 1-1-1V6zm4.995 9V5h8.004a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H7.995z" fill="currentColor"></path>
</g>
</svg>
</cosy-icon>
</cosy-tooltip>
</div>
</header>
<div class="content">
<main class="cosy-scrollbar">
<div class="article-container">
<!-- 渲染文章内容 -->
<article>
<!-- 文章标题 -->
<h1 class="post-title">码场悟道</h1>
<div class="last-updated">
上次更新: 2023-11-07 14:48:08
</div>
<!-- 文章 -->
<h1 id="模板引擎"><a href="#模板引擎" class="headerlink" title="模板引擎"></a>模板引擎</h1><p>严格的模板引擎的定义,输入模板字符串 + 数据,得到渲染过的字符串。实现上,从正则替换到拼 function 字符串到正经的 AST 解析各种各样,但从定义上来说都是差不多的。字符串渲染的性能其实也就在后端比较有意义,毕竟每一次渲染都是在消耗服务器资源,但在前端,用户只有一个,几十毫秒的渲染时间跟请求延迟比起来根本不算瓶颈。倒是前端的后续更新是字符串模板引擎的软肋,因为用渲染出来的字符串整个替换 innerHTML 是一个效率很低的更新方式。所以这样的模板引擎如今在纯前端情境下已经不再是好的选择,意义更多是在于方便前后端共用模板。</p>
<h1 id="古老数据渲染-vm-的方式"><a href="#古老数据渲染-vm-的方式" class="headerlink" title="古老数据渲染 vm 的方式"></a>古老数据渲染 vm 的方式</h1><p>这种写法,弊端太多了,玩具车</p>
<pre class="line-numbers language-markup" data-language="markup"><code class="language-markup"><span class="token doctype"><span class="token punctuation">&lt;!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>en<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>UTF-8<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">http-equiv</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>X-UA-Compatible<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>IE=edge<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>viewport<span class="token punctuation">"</span></span> <span class="token attr-name">content</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>width=device-width, initial-scale=1.0<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">></span></span>Document<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>app<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">var</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span>
<span class="token punctuation">&#123;</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"小明"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">11</span><span class="token punctuation">,</span> <span class="token literal-property property">sex</span><span class="token operator">:</span> <span class="token string">"男"</span> <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#123;</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"小红"</span><span class="token punctuation">,</span> <span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">22</span><span class="token punctuation">,</span> <span class="token literal-property property">sex</span><span class="token operator">:</span> <span class="token string">"女"</span> <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> listDOM <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">"app"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
arr<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">let</span> _li <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">"li"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
_li<span class="token punctuation">.</span>innerText <span class="token operator">=</span> item<span class="token punctuation">.</span>name<span class="token punctuation">;</span>
listDOM<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>_li<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="mustache-原理"><a href="#mustache-原理" class="headerlink" title="mustache 原理"></a>mustache 原理</h1><ul>
<li>1、先把模板字符串编译成 tokens(代号)</li>
<li>2、根据 tokens结合数据渲染成 dom</li>
</ul>
<blockquote>
<p>本质上tokens 是一个 js 嵌套数组没事模板字符串 js 的表示,他是<code>抽象语法树</code><code>虚拟节点</code>的开山鼻祖</p>
</blockquote>
<p>假设有这么一个模板字符串</p>
<pre class="line-numbers language-markup" data-language="markup"><code class="language-markup"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span>我买了一个&#123;&#123;thing&#125;&#125;,好&#123;&#123;mood&#125;&#125;<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>会编译成 tokens如下</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 这里面每一个数组行都是一个 token组起来就是 tokens</span>
<span class="token comment">// html 标签也会被看成纯文本</span>
<span class="token punctuation">[</span>
<span class="token punctuation">[</span><span class="token string">"text"</span><span class="token punctuation">,</span> <span class="token string">"&lt;h1>我买了一个"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token string">"thing"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token string">"text"</span><span class="token punctuation">,</span> <span class="token string">"好"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token string">"mood"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token string">"text"</span><span class="token punctuation">,</span> <span class="token string">"啊&lt;/h1>"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>当模板存在循环式,带层级嵌套,如下:</p>
<pre class="line-numbers language-markup" data-language="markup"><code class="language-markup"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">></span></span>
&#123;&#123;#arr&#125;&#125;
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span>&#123;&#123;.&#125;&#125;<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span>
&#123;&#123;/arr&#125;&#125;
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>会被编译成</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token punctuation">[</span>
<span class="token punctuation">[</span><span class="token string">"text"</span><span class="token punctuation">,</span> <span class="token string">"&lt;div>&lt;ul>"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span>
<span class="token string">"#"</span><span class="token punctuation">,</span>
<span class="token string">"arr"</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span>
<span class="token punctuation">[</span><span class="token string">"text"</span><span class="token punctuation">,</span> <span class="token string">"li"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token string">"."</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token string">"text"</span><span class="token punctuation">,</span> <span class="token string">"&lt;/li>"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token string">"text"</span><span class="token punctuation">,</span> <span class="token string">"&lt;/ul>&lt;/div>"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>如果是双重循环,带层级嵌套继续加一层,例如:</p>
<pre class="line-numbers language-markup" data-language="markup"><code class="language-markup"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ol</span><span class="token punctuation">></span></span>
&#123;&#123;#students&#125;&#125;
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span>
学生&#123;&#123;item.name&#125;&#125;的爱好是
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ol</span><span class="token punctuation">></span></span>
&#123;&#123;#item.hobbies&#125;&#125;
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span>&#123;&#123;.&#125;&#125;<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span>
&#123;&#123;/#item.hobbies&#125;&#125;
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ol</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span>
&#123;&#123;/#students&#125;&#125;
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ol</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>会被编译成</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token punctuation">[</span>
<span class="token punctuation">[</span><span class="token string">"text"</span><span class="token punctuation">,</span> <span class="token string">"&lt;div>&lt;ol>"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span>
<span class="token string">"#"</span><span class="token punctuation">,</span>
<span class="token string">"students"</span><span class="token punctuation">,</span>
<span class="token keyword">null</span><span class="token punctuation">,</span>
<span class="token keyword">null</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token string">"text"</span><span class="token punctuation">,</span> <span class="token string">"&lt;li>学生"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token string">"name"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"text"</span><span class="token punctuation">,</span> <span class="token string">"的爱好是&lt;ol>"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"#"</span><span class="token punctuation">,</span> <span class="token string">"hobbies"</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>
<span class="token punctuation">[</span><span class="token string">'text'</span><span class="token punctuation">,</span><span class="token string">'&lt;li>'</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token string">'name'</span><span class="token punctuation">,</span><span class="token string">'.'</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token string">'text'</span><span class="token punctuation">,</span><span class="token string">'&lt;/li>'</span><span class="token punctuation">]</span>
<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token string">'text'</span><span class="token punctuation">,</span><span class="token string">'&lt;ol>&lt;/li>'</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">[</span><span class="token string">'text'</span><span class="token punctuation">,</span><span class="token string">'&lt;/ol>&lt;/div>'</span><span class="token punctuation">]</span>
<span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<blockquote>
<p><code>mustache.js</code>中完成上述这一过程的函数<code>parseTemplate</code>,可以去找源代码看</p>
</blockquote>
<h2 id="tokens-生成算法"><a href="#tokens-生成算法" class="headerlink" title="tokens 生成算法"></a>tokens 生成算法</h2><p>用简单的模板字符串举例:</p>
<pre class="line-numbers language-markup" data-language="markup"><code class="language-markup">我买了一个&#123;&#123;thing&#125;&#125;,好&#123;&#123;mood&#125;&#125;<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>有一个指针往右遍历,从<code></code>开始,遍历到<code></code>结束,如下:</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">/**
*
* 我买了一个&#123;&#123;thing&#125;&#125;,好&#123;&#123;mood&#125;&#125;
* ↑
*
* Step1指针位置 = 1
*
* 我买了一个&#123;&#123;thing&#125;&#125;,好&#123;&#123;mood&#125;&#125;
* ↑
*
* Step2指针位置 = 2
*
* 我买了一个&#123;&#123;thing&#125;&#125;,好&#123;&#123;mood&#125;&#125;
* ↑
*
* Step3指针位置 = 4
*
* 我买了一个&#123;&#123;thing&#125;&#125;,好&#123;&#123;mood&#125;&#125;
* ↑
*
* Step4指针位置 = 11
*
* 我买了一个&#123;&#123;thing&#125;&#125;,好&#123;&#123;mood&#125;&#125;
* ↑
*
* Step5指针位置 = 15
*
* 我买了一个&#123;&#123;thing&#125;&#125;,好&#123;&#123;mood&#125;&#125;
* ↑
*
* ... while(指针位置 >= 模板字符串.length)
*
* /</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<ul>
<li>Step1:</li>
</ul>
<p>指针右移 1 个长度,以指针位置切割,字符串被分成<code></code>+<code>买了一个&#123;&#123;thing&#125;&#125;,好&#123;&#123;mood&#125;&#125;</code></p>
<ul>
<li>Step2:</li>
</ul>
<p>指针右移 1 个长度,以指针位置切割,字符串被分成<code>我买</code>+<code>了一个&#123;&#123;thing&#125;&#125;,好&#123;&#123;mood&#125;&#125;</code></p>
<ul>
<li>Step3:</li>
</ul>
<p>第一次遇到,通过 <code>indexOf(&quot;&#123;&#123;") == 0` 判断
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 标记为 text 放到 tokens 中</span>
token<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"text"</span><span class="token punctuation">,</span> <span class="token string">"我买了一个"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// tokens: [['text', '我买了一个']]</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
结束,此时指针位置 = 4
- Step4:
指针右移 2 个长度,跳过`&#123;&#123;`,暂存此时`pos_last = 6`
此时,右边字符串(尾字符串)`thing&#125;&#125;,好&#123;&#123;mood&#125;&#125;</code></p>
<p>右移 5 个长度,识别<code>模板内部数据对象</code></p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token function">substring</span><span class="token punctuation">(</span>post_last<span class="token punctuation">,</span> <span class="token number">6</span> <span class="token operator">+</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// thing 5个长度</span>
<span class="token comment">// 标记为 name 放到 tokens 中</span>
token<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"name"</span><span class="token punctuation">,</span> <span class="token string">"thing"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// tokens: [['text', '我买了一个']], ['name', 'thing']]</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<p>结束,此时指针位置 &#x3D; 11</p>
<ul>
<li>Step5:</li>
</ul>
<blockquote>
<p>遇到 <code>&#125;&#125;</code>,通过 <code>indexOf(&quot;&#125;&#125;&quot;) == 0</code>判断</p>
</blockquote>
<p>指针右移 2 个长度,跳过<code>&#125;&#125;</code>,暂存此时<code>post_last = 13</code>,继续右移 2 个长度</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token function">substring</span><span class="token punctuation">(</span>post_last<span class="token punctuation">,</span> <span class="token number">13</span> <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// ,好 2个长度</span>
<span class="token comment">// 标记为 text 放到 tokens 中</span>
token<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"text"</span><span class="token punctuation">,</span> <span class="token string">",好"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// tokens: [['text', '我买了一个']], ['name', 'thing'],['text', ',好' ]]</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<blockquote>
<p>第二次,遇到 <code>&#123;&#123;`
剩下循环执行就行了,这个过程,我们可以称作`扫描 Scan`
## 扫描器 Scanner
新建一个 `Scanner.js`,用来扫描模板字符串,实现上面的原理
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">/**
* 模板字符串扫描器
*/</span>
<span class="token keyword">class</span> <span class="token class-name">Scanner</span> <span class="token punctuation">&#123;</span>
<span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">templ</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>templ <span class="token operator">=</span> templ<span class="token punctuation">;</span> <span class="token comment">// 模板字符串</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>tail <span class="token operator">=</span> templ<span class="token punctuation">;</span> <span class="token comment">// 尾字符串</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>pPos <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// 指针位置</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">/**
* 指针跳过模板标签
* @param &#123;模板语法包围标签&#125; tag
*/</span>
<span class="token function">jumpTag</span><span class="token punctuation">(</span><span class="token parameter">tag</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>tail<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>tag<span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>pPos <span class="token operator">+=</span> tag<span class="token punctuation">.</span>length<span class="token punctuation">;</span> <span class="token comment">// 指针右移 tag.length 个长度</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>tail <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>templ<span class="token punctuation">.</span><span class="token function">substring</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>pPos<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 尾字符串更新</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">/**
* 指针遇见模板标签 &#123;&#123;
* @param &#123;模板语法包围标签&#125; tag
*/</span>
<span class="token function">missTag</span><span class="token punctuation">(</span><span class="token parameter">tag</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">let</span> pPos_last <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>pPos<span class="token punctuation">;</span>
<span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">eof</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;&amp;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>tail<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>tag<span class="token punctuation">)</span> <span class="token operator">!==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>pPos<span class="token operator">++</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>tail <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>templ<span class="token punctuation">.</span><span class="token function">substring</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>pPos<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>templ<span class="token punctuation">.</span><span class="token function">substring</span><span class="token punctuation">(</span>pPos_last<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>pPos<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token function">eof</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>pPos <span class="token operator">>=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>templ<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
## 分析器 Parser
调用`Scanner.js`
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> tmpl <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">我买了一个&#123;&#123;thing&#125;&#125;,好&#123;&#123;mood&#125;&#125;</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>
<span class="token comment">// 编译 模板字符串 => tokens</span>
<span class="token keyword">const</span> Parser <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
<span class="token function-variable function">createTokens</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">tmpl</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span>
<span class="token keyword">let</span> scanner <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Scanner</span><span class="token punctuation">(</span>tmpl<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> tokens <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token comment">// scanner 循环执行</span>
<span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token operator">!</span>scanner<span class="token punctuation">.</span><span class="token function">eof</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
ctx <span class="token operator">=</span> scanner<span class="token punctuation">.</span><span class="token function">missTag</span><span class="token punctuation">(</span><span class="token string">"&#123;&#123;"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 返回 头字符串</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>ctx <span class="token operator">!=</span> <span class="token string">""</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
tokens<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"text"</span><span class="token punctuation">,</span> ctx<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
scanner<span class="token punctuation">.</span><span class="token function">jumpTag</span><span class="token punctuation">(</span><span class="token string">"&#123;&#123;"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 跳过 模板字符</span>
ctx <span class="token operator">=</span> scanner<span class="token punctuation">.</span><span class="token function">missTag</span><span class="token punctuation">(</span><span class="token string">"&#125;&#125;"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 返回 &#123;&#123; x &#125;&#125;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>ctx <span class="token operator">!=</span> <span class="token string">""</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
tokens<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"name"</span><span class="token punctuation">,</span> ctx<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
scanner<span class="token punctuation">.</span><span class="token function">jumpTag</span><span class="token punctuation">(</span><span class="token string">"&#125;&#125;"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">return</span> tokens<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Parser<span class="token punctuation">.</span><span class="token function">createTokens</span><span class="token punctuation">(</span>tmpl<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 输出,非常的 奈一丝</span>
<span class="token comment">// ["text", "我买了一个"]</span>
<span class="token comment">// ["name", "thing"]</span>
<span class="token comment">// ["text", ",好"]</span>
<span class="token comment">// ["name", "mood"]</span>
<span class="token comment">// ["text", "啊"]</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
## 扫描器 Scanner 增强
上面的`Parser`只能识别`&#123;&#123;`和`&#125;&#125;</code>,如果模板语法复杂一点,比如加入 <code>&#123;&#123;#list&#125;&#125;...&#123;&#123;/list&#125;&#125;</code>,需要增强<code>Parser</code></p>
</blockquote>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> template <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">
哈哈哈
&#123;&#123;#students&#125;&#125;
我买了一个 &#123;&#123; thing &#125;&#125;,好&#123;&#123;mood&#125;&#125;&#123;&#123;a&#125;&#125;
&#123;&#123;item.name&#125;&#125;
&#123;&#123;/students&#125;&#125;
</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>
<span class="token keyword">const</span> Parser <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
<span class="token function-variable function">createTokens</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">tmpl</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span>
<span class="token keyword">let</span> scanner <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Scanner</span><span class="token punctuation">(</span>tmpl<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> tokens <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> ctx <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span>
<span class="token comment">// scanner 循环执行</span>
<span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token operator">!</span>scanner<span class="token punctuation">.</span><span class="token function">eof</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
ctx <span class="token operator">=</span> scanner<span class="token punctuation">.</span><span class="token function">missTag</span><span class="token punctuation">(</span><span class="token string">"&#123;&#123;"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 返回 头字符串</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>ctx <span class="token operator">!=</span> <span class="token string">""</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
tokens<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"text"</span><span class="token punctuation">,</span> ctx<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
scanner<span class="token punctuation">.</span><span class="token function">jumpTag</span><span class="token punctuation">(</span><span class="token string">"&#123;&#123;"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 跳过 模板字符</span>
ctx <span class="token operator">=</span> scanner<span class="token punctuation">.</span><span class="token function">missTag</span><span class="token punctuation">(</span><span class="token string">"&#125;&#125;"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 返回 &#123;&#123; x &#125;&#125;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>ctx <span class="token operator">!=</span> <span class="token string">""</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">switch</span> <span class="token punctuation">(</span>ctx<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">case</span> <span class="token string">"#"</span><span class="token operator">:</span>
tokens<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"#"</span><span class="token punctuation">,</span> ctx<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// &#123;&#123;# x &#125;&#125;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token keyword">case</span> <span class="token string">"/"</span><span class="token operator">:</span>
tokens<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"/"</span><span class="token punctuation">,</span> ctx<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token keyword">default</span><span class="token operator">:</span>
tokens<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"name"</span><span class="token punctuation">,</span> ctx<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
scanner<span class="token punctuation">.</span><span class="token function">jumpTag</span><span class="token punctuation">(</span><span class="token string">"&#125;&#125;"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">return</span> tokens<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Parser<span class="token punctuation">.</span><span class="token function">createTokens</span><span class="token punctuation">(</span>template<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 输出</span>
<span class="token comment">// ["text", "↵ 哈哈哈↵ "]</span>
<span class="token comment">// ["#", "students"]</span>
<span class="token comment">// ["text", "↵ 我买了一个 "]</span>
<span class="token comment">// ["name", " thing "]</span>
<span class="token comment">// ["text", ",好"]</span>
<span class="token comment">// ["name", "mood"]</span>
<span class="token comment">// ["text", "啊"]</span>
<span class="token comment">// ["name", "a"]</span>
<span class="token comment">// ["text", "↵ "]</span>
<span class="token comment">// ["name", "item.name"]</span>
<span class="token comment">// ["text", "↵ "]</span>
<span class="token comment">// ["/", "students"]</span>
<span class="token comment">// ["text", "↵ "]</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="栈队列算法"><a href="#栈队列算法" class="headerlink" title="栈队列算法"></a>栈队列算法</h2><p>上一步最后的输出,只有单层嵌套,如果是两层嵌套怎么办?</p>
<p>例如模板语法如下:</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> template <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">
哈哈哈
&#123;&#123;#students&#125;&#125;
&#123;&#123;#stu&#125;&#125;
&#123;&#123;stu.name&#125;&#125;买了一个 &#123;&#123; thing &#125;&#125;,好&#123;&#123;mood&#125;&#125;&#123;&#123;a&#125;&#125;
&#123;&#123;/stu&#125;&#125;
&#123;&#123;item.name&#125;&#125;
&#123;&#123;/students&#125;&#125;
</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>经过<code>Parser</code>处理得到:</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">/**
*
* ["text", "↵ 哈哈哈↵ "]
* ["#", "students"]
* ["text", "↵ "]
* ["#", "stu"]
* ["text", "↵ "]
* ["name", "stu.name"]
* ["text", "买了一个 "]
* ["name", " thing "]
* ["text", ",好"]
* ["name", "mood"]
* ["text", "啊"]
* ["name", "a"]
* ["text", "↵ "]
* ["/", "stu"]
* ["text", "↵ "]
* ["name", "item.name"]
* ["text", "↵ "]
* ["/", "students"]
* ["text", "↵ "]
*
* /</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>此时<code>students</code><code>stu</code>都是<code>#</code>标记,我们需要利用算法处理他们的嵌套结构,处理成大约如下这样的结构:</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">/**
*
* ["text", "↵ 哈哈哈↵ "]
* Array(3)
* "#"
* "students"
* Array(5)
* ["text", "↵ "]
* ["#", "stu", Array(9)]
* ["text", "↵ "]
* ["name", "item.name"]
* ["text", "↵ "]
* ["text", "↵ "]
*
* /</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="常用工具类"><a href="#常用工具类" class="headerlink" title="常用工具类"></a>常用工具类</h1><h2 id="递归"><a href="#递归" class="headerlink" title="递归"></a>递归</h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">/**
* &#123;string&#125; dir 递归根目录
* &#123;object&#125; list 暂存参数
*/</span>
<span class="token keyword">const</span> <span class="token function-variable function">deep</span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token parameter">dir<span class="token punctuation">,</span> list <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span>
<span class="token keyword">const</span> dirs <span class="token operator">=</span> <span class="token keyword">await</span> fs<span class="token punctuation">.</span>promises<span class="token punctuation">.</span><span class="token function">readdir</span><span class="token punctuation">(</span>dir<span class="token punctuation">)</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> dirs<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">const</span> item <span class="token operator">=</span> dirs<span class="token punctuation">[</span>i<span class="token punctuation">]</span>
<span class="token keyword">const</span> itemPath <span class="token operator">=</span> path<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span>dir<span class="token punctuation">,</span> item<span class="token punctuation">)</span>
<span class="token keyword">const</span> isDir <span class="token operator">=</span> fs<span class="token punctuation">.</span><span class="token function">statSync</span><span class="token punctuation">(</span>itemPath<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">isDirectory</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
isDir <span class="token operator">?</span> <span class="token keyword">await</span> <span class="token function">deep</span><span class="token punctuation">(</span>itemPath<span class="token punctuation">,</span> list<span class="token punctuation">)</span> <span class="token operator">:</span> list<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>itemPath<span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">return</span> list
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="自增id短码"><a href="#自增id短码" class="headerlink" title="自增id短码"></a>自增id短码</h2><p>用于连接分享</p>
<pre class="line-numbers language-typescript" data-language="typescript"><code class="language-typescript"><span class="token keyword">const</span> <span class="token function-variable function">createAscString</span> <span class="token operator">=</span> <span class="token punctuation">(</span>id<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span>
<span class="token keyword">const</span> dictionary <span class="token operator">=</span> <span class="token punctuation">[</span>
<span class="token string">"0123456789"</span><span class="token punctuation">,</span>
<span class="token string">"abcdefghigklmnopqrstuvwxyz"</span><span class="token punctuation">,</span>
<span class="token string">"ABCDEFGHIGKLMNOPQRSTUVWXYZ"</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> chars <span class="token operator">=</span> dictionary<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
radix <span class="token operator">=</span> chars<span class="token punctuation">.</span>length<span class="token punctuation">,</span>
qutient <span class="token operator">=</span> <span class="token number">1000</span> <span class="token operator">*</span> <span class="token number">1000</span> <span class="token operator">*</span> <span class="token number">9999</span> <span class="token operator">+</span> <span class="token operator">+</span>id<span class="token punctuation">,</span>
arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">while</span> <span class="token punctuation">(</span>qutient<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
mod <span class="token operator">=</span> qutient <span class="token operator">%</span> radix<span class="token punctuation">;</span>
qutient <span class="token operator">=</span> <span class="token punctuation">(</span>qutient <span class="token operator">-</span> mod<span class="token punctuation">)</span> <span class="token operator">/</span> radix<span class="token punctuation">;</span>
arr<span class="token punctuation">.</span><span class="token function">unshift</span><span class="token punctuation">(</span>chars<span class="token punctuation">[</span>mod<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">return</span> arr<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token builtin">console</span><span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">createAscString</span><span class="token punctuation">(</span><span class="token number">100000000</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="手动实现-eventBus"><a href="#手动实现-eventBus" class="headerlink" title="手动实现 eventBus"></a>手动实现 eventBus</h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">class</span> <span class="token class-name">EventBus</span> <span class="token punctuation">&#123;</span>
<span class="token function">constructor</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token comment">// key-value : eventName-date</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>callbacks <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">/**
* 监听事件
* @param &#123;事件名&#125; eventName
* @param &#123;回调函数&#125; callback
*/</span>
<span class="token function">on</span><span class="token punctuation">(</span><span class="token parameter">eventName<span class="token punctuation">,</span> callback</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">checkType</span><span class="token punctuation">(</span>eventName<span class="token punctuation">)</span><span class="token punctuation">.</span>callbacks<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span>
<span class="token operator">?</span> <span class="token function">callback</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>callbacks<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span><span class="token punctuation">)</span>
<span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">The event has not been declared</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">/**
* 注册一个事件
* @param &#123;事件名&#125; eventName
* @param &#123;传递的对象&#125; data
*/</span>
<span class="token function">emit</span><span class="token punctuation">(</span><span class="token parameter">eventName<span class="token punctuation">,</span> data</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">checkType</span><span class="token punctuation">(</span>eventName<span class="token punctuation">)</span><span class="token punctuation">.</span>callbacks<span class="token punctuation">[</span>eventName<span class="token punctuation">]</span> <span class="token operator">=</span> data<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">/**
* 注销事件,不传参数默认注销全部事件
* @param &#123;事件名&#125; eventName
*/</span>
<span class="token function">off</span><span class="token punctuation">(</span><span class="token parameter">eventName</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
eventName
<span class="token operator">?</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">checkType</span><span class="token punctuation">(</span>eventName<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">removeEvent</span><span class="token punctuation">(</span>eventName<span class="token punctuation">)</span>
<span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">emptyEvent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">/**
* 移出事件
* @param &#123;事件名&#125; eventName
*/</span>
<span class="token function">removeEvent</span><span class="token punctuation">(</span><span class="token parameter">eventName</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
Reflect<span class="token punctuation">.</span><span class="token function">deleteProperty</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>callbacks<span class="token punctuation">,</span> eventName<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">/**
* 清空全部事件
*/</span>
<span class="token function">emptyEvent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>callbacks <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">/**
* 参数类型校验
* @param &#123;参数&#125; param
* @param &#123;合法的类型&#125; validType
*/</span>
<span class="token function">checkType</span><span class="token punctuation">(</span>param<span class="token punctuation">,</span> validType <span class="token operator">=</span> <span class="token string">"string"</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> param <span class="token operator">!==</span> validType<span class="token punctuation">)</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">(param, </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>param<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">) should be of </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>validType<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string"> type</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span> <span class="token comment">// 缅怀jQ链式调用</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">/**
* 错误提示
* @param &#123;提示文字&#125; text
*/</span>
<span class="token function">error</span><span class="token punctuation">(</span><span class="token parameter">text</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span>text<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>调用</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 省略import</span>
<span class="token keyword">const</span> eventBus <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">EventBus</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
eventBus<span class="token punctuation">.</span><span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">"login"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">&#123;</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">d</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">&#125;</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
eventBus<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token number">123</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">d</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>d<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [&#123;...&#125;]</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="判断对象是否有某个-key"><a href="#判断对象是否有某个-key" class="headerlink" title="判断对象是否有某个 key"></a>判断对象是否有某个 key</h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">&#123;</span> <span class="token literal-property property">alias</span><span class="token operator">:</span> <span class="token string">"es6"</span> <span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token string">"alias"</span> <span class="token keyword">in</span> obj<span class="token punctuation">;</span> <span class="token comment">// true</span>
Reflect<span class="token punctuation">.</span><span class="token function">has</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token string">"alias"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<h2 id="浏览器"><a href="#浏览器" class="headerlink" title="浏览器"></a>浏览器</h2><h2 id="版本信息"><a href="#版本信息" class="headerlink" title="版本信息"></a>版本信息</h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">window<span class="token punctuation">.</span>navigator<span class="token punctuation">.</span>userAgent<span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<h2 id="兼容事件绑定"><a href="#兼容事件绑定" class="headerlink" title="兼容事件绑定"></a>兼容事件绑定</h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">/*
兼容低版本IEele为需要绑定事件的元素
eventName为事件名保持addEventListener语法去掉onfun为事件响应函数
*/</span>
<span class="token keyword">function</span> <span class="token function">addEvent</span><span class="token punctuation">(</span><span class="token parameter">ele<span class="token punctuation">,</span> eventName<span class="token punctuation">,</span> fun</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
ele<span class="token punctuation">.</span>addEventListener
<span class="token operator">?</span> ele<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span>eventName<span class="token punctuation">,</span> fun<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span>
<span class="token operator">:</span> ele<span class="token punctuation">.</span><span class="token function">attachEvent</span><span class="token punctuation">(</span><span class="token string">"on"</span> <span class="token operator">+</span> eventNme<span class="token punctuation">,</span> fun<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="数组对象"><a href="#数组对象" class="headerlink" title="数组对象"></a>数组对象</h2><h2 id="reduce"><a href="#reduce" class="headerlink" title="reduce"></a>reduce</h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> sum <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">prev<span class="token punctuation">,</span> cur<span class="token punctuation">,</span> index<span class="token punctuation">,</span> arr</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>prev<span class="token punctuation">,</span> cur<span class="token punctuation">,</span> index<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> prev <span class="token operator">+</span> cur<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token comment">//注意这里设置了初始值</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">,</span> sum<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 求和</span>
<span class="token keyword">const</span> sum <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">p<span class="token punctuation">,</span>c</span><span class="token punctuation">)</span> <span class="token operator">=></span> p<span class="token operator">+</span>c<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="对象内部根据-key-对-value-进行排序-取前-3"><a href="#对象内部根据-key-对-value-进行排序-取前-3" class="headerlink" title="对象内部根据 key 对 value 进行排序,取前 3"></a>对象内部根据 key 对 value 进行排序,取前 3</h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> datasource <span class="token operator">=</span> <span class="token punctuation">[</span>
<span class="token punctuation">&#123;</span> <span class="token literal-property property">price</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">alias</span><span class="token operator">:</span> <span class="token string">"watermelon"</span> <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#123;</span> <span class="token literal-property property">price</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">alias</span><span class="token operator">:</span> <span class="token string">"orange"</span> <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#123;</span> <span class="token literal-property property">price</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">alias</span><span class="token operator">:</span> <span class="token string">"banana"</span> <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#123;</span> <span class="token literal-property property">price</span><span class="token operator">:</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token literal-property property">alias</span><span class="token operator">:</span> <span class="token string">"apple"</span> <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token comment">// 降序排列</span>
<span class="token keyword">let</span> <span class="token function-variable function">compare</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">key</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token operator">=></span> b<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">-</span> a<span class="token punctuation">[</span>key<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> sorted <span class="token operator">=</span> datasource
<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token function">compare</span><span class="token punctuation">(</span><span class="token string">"price"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">i</span><span class="token punctuation">)</span> <span class="token operator">=></span> i<span class="token punctuation">[</span><span class="token string">"alias"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 返回 ["apple", "orange", "banana"]</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="随机字符串"><a href="#随机字符串" class="headerlink" title="随机字符串"></a>随机字符串</h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> <span class="token function-variable function">getRandomRangeNum</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">len <span class="token operator">=</span> <span class="token number">32</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span>
<span class="token comment">// 略去不宜辨识字符</span>
<span class="token keyword">let</span> dictionary <span class="token operator">=</span> <span class="token string">"ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz"</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> maxPos <span class="token operator">=</span> dictionary<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
<span class="token keyword">let</span> res <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> len<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
res <span class="token operator">+=</span> dictionary<span class="token punctuation">.</span><span class="token function">charAt</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span> maxPos<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">return</span> res<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="类型检测"><a href="#类型检测" class="headerlink" title="类型检测"></a>类型检测</h2><p>Q使用<code>typeof foo === &quot;object&quot;</code>检测<code>foo</code>是否为对象有什么缺点?如何避免?</p>
<p>A<code>typeof</code> 是否能准确判断一个对象变量,答案是否定的,<code>null</code> 的结果也是 <code>object</code><code>Array</code> 的结果也是 <code>object</code>,有时候我们需要的是 “纯粹” 的 <code>object</code> 对象</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token class-name">Object</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token string">"[object Object]"</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<h2 id="倒计时"><a href="#倒计时" class="headerlink" title="倒计时"></a>倒计时</h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">class</span> <span class="token class-name">Countdown</span> <span class="token punctuation">&#123;</span>
<span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">startNum<span class="token punctuation">,</span> endNum<span class="token punctuation">,</span> interval</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token punctuation">[</span><span class="token keyword">this</span><span class="token punctuation">.</span>startNum<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>endNum<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>interval<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span>startNum<span class="token punctuation">,</span> endNum<span class="token punctuation">,</span> interval<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token function">execute</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">var</span> timer <span class="token operator">=</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>startNum <span class="token operator">>=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>endNum<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>startNum<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>startNum <span class="token operator">-=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">execute</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
<span class="token function">clearTimeout</span><span class="token punctuation">(</span>timer<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>interval<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// 实例化调用</span>
<span class="token keyword">var</span> countdown <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Countdown</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">execute</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="范围随机数"><a href="#范围随机数" class="headerlink" title="范围随机数"></a>范围随机数</h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 能取到 min取不到 max</span>
<span class="token keyword">function</span> <span class="token function">getRandomRangeNum</span><span class="token punctuation">(</span><span class="token parameter">min<span class="token punctuation">,</span> max</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> min <span class="token operator">+</span> Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token punctuation">(</span>max <span class="token operator">-</span> min<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="获取当前月的天数"><a href="#获取当前月的天数" class="headerlink" title="获取当前月的天数"></a>获取当前月的天数</h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> getCurMonthDays <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>
<span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getFullYear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getMonth</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span>
<span class="token number">0</span>
<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="对象小操作"><a href="#对象小操作" class="headerlink" title="对象小操作"></a>对象小操作</h1><h2 id="去虚假值"><a href="#去虚假值" class="headerlink" title="去虚假值"></a>去虚假值</h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> arr4 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"小明"</span><span class="token punctuation">,</span> <span class="token string">"小蓝"</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token string">" "</span><span class="token punctuation">,</span> <span class="token keyword">undefined</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">NaN</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr4<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span>Boolean<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// => ['小明', '小蓝', ' ', true]</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<h2 id="头尾插入"><a href="#头尾插入" class="headerlink" title="头尾插入"></a>头尾插入</h2><p>效率比 <code>unshift()</code></p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token comment">// 头插入</span>
<span class="token punctuation">[</span><span class="token string">"haha"</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 尾插入</span>
arr<span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">"haha"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="删除属性"><a href="#删除属性" class="headerlink" title="删除属性"></a>删除属性</h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">deleteA</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">delete</span> obj<span class="token punctuation">.</span><span class="token constant">A</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> obj<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// 使用解构赋值</span>
<span class="token keyword">const</span> <span class="token function-variable function">deleteA</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">&#123;</span> <span class="token constant">A</span><span class="token punctuation">,</span> <span class="token operator">...</span>rest <span class="token punctuation">&#125;</span> <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> rest<span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="生产、加工、消费分离"><a href="#生产、加工、消费分离" class="headerlink" title="生产、加工、消费分离"></a>生产、加工、消费分离</h1><ul>
<li>从接口拿数据到视图 fetch api</li>
<li>加工 computed</li>
<li>消费 v-for</li>
</ul>
<h1 id="元数据"><a href="#元数据" class="headerlink" title="元数据"></a>元数据</h1><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">import</span> <span class="token string">"reflect-metadata"</span><span class="token punctuation">;</span> <span class="token comment">// npm install reflect-metadata</span>
<span class="token keyword">function</span> <span class="token function">Role</span><span class="token punctuation">(</span><span class="token parameter"><span class="token literal-property property">name</span><span class="token operator">:</span> string</span><span class="token punctuation">)</span><span class="token operator">:</span> ClassDecorator <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token parameter">target</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span>
Reflect<span class="token punctuation">.</span><span class="token function">defineMetadata</span><span class="token punctuation">(</span><span class="token string">"role"</span><span class="token punctuation">,</span> name<span class="token punctuation">,</span> target<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
@<span class="token function">Role</span><span class="token punctuation">(</span><span class="token string">"admin"</span><span class="token punctuation">)</span>
<span class="token keyword">class</span> <span class="token class-name">Post</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span>
<span class="token keyword">const</span> metadata <span class="token operator">=</span> Reflect<span class="token punctuation">.</span><span class="token function">getMetadata</span><span class="token punctuation">(</span><span class="token string">"role"</span><span class="token punctuation">,</span> Post<span class="token punctuation">)</span><span class="token punctuation">;</span>
Reflect<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>Post<span class="token punctuation">,</span> <span class="token string">"role2"</span><span class="token punctuation">,</span> metadata<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Reflect<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>Post<span class="token punctuation">,</span> <span class="token string">"role2"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// admin</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="防抖与节流"><a href="#防抖与节流" class="headerlink" title="防抖与节流"></a>防抖与节流</h1><p>在页面上监听诸如<code>scroll</code>(页面滚动),<code>mousemove</code>(鼠标移动) <code>keydown</code> <code>keyup</code> <code>keypress</code>(按下键盘)等等一系列事件的时候,我们并不希望频繁的触发这类监听,尤其当请求非常消耗资源时,这种操作会导致服务器性能急剧下降。</p>
<h2 id="Debounce"><a href="#Debounce" class="headerlink" title="Debounce"></a>Debounce</h2><p>把触发非常频繁的事件合并成一次延迟执行,如果对监听函数使用 100ms 的容忍时间,那么时间在第 3.1s 的时候执行</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 默认延时100ms</span>
<span class="token keyword">function</span> <span class="token function">debounce</span><span class="token punctuation">(</span><span class="token parameter">func<span class="token punctuation">,</span> dealy <span class="token operator">=</span> <span class="token number">100</span></span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">let</span> timer<span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token comment">// 暂存this和参数</span>
<span class="token keyword">let</span> _this <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> args <span class="token operator">=</span> arguments<span class="token punctuation">;</span>
<span class="token comment">// 清除定时器确保不执行func</span>
<span class="token function">clearTimeout</span><span class="token punctuation">(</span>timer<span class="token punctuation">)</span><span class="token punctuation">;</span>
timer <span class="token operator">=</span> <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token function">func</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>_this<span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span> dealy<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// 执行函数</span>
<span class="token keyword">function</span> <span class="token function">handler</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">delay 100ms ,then handle</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// dom添加监听</span>
document
<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#someNode"</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"scroll"</span><span class="token punctuation">,</span> <span class="token function">debounce</span><span class="token punctuation">(</span>handler<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="Throttle"><a href="#Throttle" class="headerlink" title="Throttle"></a>Throttle</h2><p>固定函数执行的速率,即所谓的“节流”。设置一个阀值,在阀值内,把触发的事件合并成一次执行;当到达阀值,必定执行一次事件。</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">throttle</span><span class="token punctuation">(</span><span class="token parameter">func<span class="token punctuation">,</span> delay</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">let</span> statTime <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">let</span> currentTime <span class="token operator">=</span> <span class="token operator">+</span><span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>currentTime <span class="token operator">-</span> statTime <span class="token operator">></span> delay<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token function">func</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> arguments<span class="token punctuation">)</span><span class="token punctuation">;</span>
statTime <span class="token operator">=</span> currentTime<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// 执行函数</span>
<span class="token keyword">function</span> <span class="token function">resizeHandler</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">resize</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// window添加监听</span>
window<span class="token punctuation">.</span>onresize <span class="token operator">=</span> <span class="token function">throttle</span><span class="token punctuation">(</span>resizeHandler<span class="token punctuation">,</span> <span class="token number">300</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="this-指向"><a href="#this-指向" class="headerlink" title="this 指向"></a>this 指向</h1><h2 id="全局环境"><a href="#全局环境" class="headerlink" title="全局环境"></a>全局环境</h2><p>全局环境下this 始终指向全局对象window无论是否严格模式</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span> <span class="token operator">===</span> window<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">37</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>window<span class="token punctuation">.</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 37</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<h2 id="函数上下文调用"><a href="#函数上下文调用" class="headerlink" title="函数上下文调用"></a>函数上下文调用</h2><ul>
<li>非严格模式</li>
</ul>
<p>没有被上一级的对象所调用, this 默认指向全局对象 window</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">f1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token function">f1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">===</span> window<span class="token punctuation">;</span> <span class="token comment">// true</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<ul>
<li>严格模式</li>
</ul>
<p>this 指向 undefined</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">f2</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token string">"use strict"</span><span class="token punctuation">;</span> <span class="token comment">// 这里是严格模式</span>
<span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token function">f2</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token comment">// true</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="箭头函数"><a href="#箭头函数" class="headerlink" title="箭头函数"></a>箭头函数</h2><blockquote>
<p>箭头函数中call()、apply()、bind()方法无效</p>
</blockquote>
<p>在全局代码中,箭头函数被设置为全局对象,总之箭头函数不改变 this 指向</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> globalObject <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> <span class="token function-variable function">foo</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">this</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">===</span> globalObject<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<p>箭头函数作为对象的方法使用,指向全局 window 对象</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
<span class="token literal-property property">i</span><span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">,</span>
<span class="token function-variable function">b</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>i<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token function-variable function">c</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>i<span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
obj<span class="token punctuation">.</span><span class="token function">b</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined window&#123;...&#125;</span>
obj<span class="token punctuation">.</span><span class="token function">c</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 10 Object &#123;...&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>箭头函数可以让 this 指向固化,这种特性很有利于封装回调函数</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 总是指向 handler 对象。如果不使用箭头函数则指向全局 document 对象</span>
<span class="token keyword">var</span> handler <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
<span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token string">"123456"</span><span class="token punctuation">,</span>
<span class="token function-variable function">init</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span>
<span class="token string">"click"</span><span class="token punctuation">,</span>
<span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">doSomething</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>type<span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token boolean">false</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token function-variable function">doSomething</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">type</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Handling "</span> <span class="token operator">+</span> type <span class="token operator">+</span> <span class="token string">" for "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="call-apply-bind-与-es6"><a href="#call-apply-bind-与-es6" class="headerlink" title="call, apply, bind 与 es6"></a>call, apply, bind 与 es6</h1><p>js 的函数继承于<code>Function.prototype</code>对象,因此每个函数都会有 apply、call、bind 方法</p>
<blockquote>
<p>call 和 apply 的作用,完全一样,唯一的区别就是在参数上面。</p>
</blockquote>
<p><code>call, apply, bind</code>改变函数中 <code>this 指向</code> 的三兄弟,把<code>this</code>绑定到第一个参数对象上</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">displayHobbies</span><span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>hobbies</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string"> likes </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>hobbies<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">", "</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">.</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// 下面两个等价</span>
<span class="token function">displayHobbies</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Bob"</span> <span class="token punctuation">&#125;</span><span class="token punctuation">,</span> <span class="token string">"swimming"</span><span class="token punctuation">,</span> <span class="token string">"basketball"</span><span class="token punctuation">,</span> <span class="token string">"anime"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Bob likes swimming, basketball, anime.</span>
<span class="token function">displayHobbies</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Bob"</span> <span class="token punctuation">&#125;</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"swimming"</span><span class="token punctuation">,</span> <span class="token string">"basketball"</span><span class="token punctuation">,</span> <span class="token string">"anime"</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Bob likes swimming, basketball, anime.</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p><code>bind</code>返回的是一个函数,需要手动执行</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> p1 <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
<span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"张三"</span><span class="token punctuation">,</span>
<span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">12</span><span class="token punctuation">,</span>
<span class="token function-variable function">func</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">姓名:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">,年龄:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span><span class="token keyword">this</span><span class="token punctuation">.</span>age<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> p2 <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
<span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"李四"</span><span class="token punctuation">,</span>
<span class="token literal-property property">age</span><span class="token operator">:</span> <span class="token number">15</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
p1<span class="token punctuation">.</span><span class="token function">func</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>p2<span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//姓名:李四,年龄:15</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="for-循环优化"><a href="#for-循环优化" class="headerlink" title="for 循环优化"></a>for 循环优化</h1><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 每次都要计算array.length</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> array<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// 使用leng缓存array长度</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> length <span class="token operator">=</span> array<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i <span class="token operator">&lt;</span> length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="数组"><a href="#数组" class="headerlink" title="数组"></a>数组</h1><h2 id="扁平化去重升序排列"><a href="#扁平化去重升序排列" class="headerlink" title="扁平化去重升序排列"></a>扁平化去重升序排列</h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">11</span><span class="token punctuation">,</span> <span class="token number">12</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">12</span><span class="token punctuation">,</span> <span class="token number">13</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">14</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
arr<span class="token punctuation">.</span><span class="token function">flat</span><span class="token punctuation">(</span><span class="token number">Infinity</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]</span>
<span class="token keyword">let</span> result <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Set</span><span class="token punctuation">(</span>arr<span class="token punctuation">.</span><span class="token function">flat</span><span class="token punctuation">(</span><span class="token number">Infinity</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span> <span class="token operator">=></span> a <span class="token operator">-</span> b<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="前端页面埋点-1x1-gif"><a href="#前端页面埋点-1x1-gif" class="headerlink" title="前端页面埋点 - 1x1.gif"></a>前端页面埋点 - 1x1.gif</h1><p>通常用在,统计页面点击,曝光,停留时间,签发……等场景</p>
<ul>
<li>比 PNG&#x2F;JPG 体积小</li>
<li>天然跨域</li>
</ul>
<pre class="line-numbers language-markup" data-language="markup"><code class="language-markup"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token special-attr"><span class="token attr-name">onClick</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span><span class="token value javascript language-javascript"><span class="token function">countClick</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span><span class="token punctuation">"</span></span></span><span class="token punctuation">></span></span>haorooms<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">function</span> <span class="token function">countClick</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">new</span> <span class="token class-name">Image</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>src <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">./haorooms.gif?</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>key<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">=</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>value<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">&amp;</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string"> </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="事件委托"><a href="#事件委托" class="headerlink" title="事件委托"></a>事件委托</h1><p>利用冒泡原理,委托父元素执行</p>
<pre class="line-numbers language-markup" data-language="markup"><code class="language-markup"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span>苹果<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span>香蕉<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span>凤梨<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"ul"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function-variable function">onclick</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span>
<span class="token keyword">let</span> target <span class="token operator">=</span> event<span class="token punctuation">.</span>target<span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>target<span class="token punctuation">.</span>nodeName <span class="token operator">===</span> <span class="token string">"LI"</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>target<span class="token punctuation">.</span>innerHTML<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="构造函数-原型模式"><a href="#构造函数-原型模式" class="headerlink" title="构造函数 + 原型模式"></a>构造函数 + 原型模式</h1><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">Person</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> age<span class="token punctuation">,</span> job</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>job <span class="token operator">=</span> job<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token class-name">Person</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">say</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">text</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">say:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>text<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="剩余参数…args"><a href="#剩余参数…args" class="headerlink" title="剩余参数…args"></a>剩余参数…args</h1><p>剩余参数<code>args</code>数个数组,<code>...</code>解构符</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">fun1</span><span class="token punctuation">(</span><span class="token parameter">param<span class="token punctuation">,</span> <span class="token operator">...</span>args</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token function">alert</span><span class="token punctuation">(</span>args<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<h1 id="跨页面通信"><a href="#跨页面通信" class="headerlink" title="跨页面通信"></a>跨页面通信</h1><ul>
<li>cookie</li>
<li>web worker</li>
<li>localstorage</li>
</ul>
<h1 id="iframe-跨域通信和不跨域通信"><a href="#iframe-跨域通信和不跨域通信" class="headerlink" title="iframe 跨域通信和不跨域通信"></a>iframe 跨域通信和不跨域通信</h1><h2 id="不跨域"><a href="#不跨域" class="headerlink" title="不跨域"></a>不跨域</h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// fatherSay是父页面全局方法</span>
window<span class="token punctuation">.</span>parent<span class="token punctuation">.</span><span class="token function">fatherSay</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 父页面Dom</span>
window<span class="token punctuation">.</span>parent<span class="token punctuation">.</span>document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">"元素id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 副业页面获取frameID为`iframe_ID`的子页面的Dom</span>
window<span class="token punctuation">.</span>frames<span class="token punctuation">[</span><span class="token string">"iframe_ID"</span><span class="token punctuation">]</span><span class="token punctuation">.</span>document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">"元素id"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="跨域-postMessage"><a href="#跨域-postMessage" class="headerlink" title="跨域 postMessage"></a>跨域 postMessage</h2><p>子页面</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">window<span class="token punctuation">.</span>parent<span class="token punctuation">.</span><span class="token function">postMessage</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">,</span> <span class="token string">"http://127.0.0.1:8089"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>父页面接受</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">window<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">"message"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token function">alert</span><span class="token punctuation">(</span><span class="token number">123</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<h1 id="对象类型判断"><a href="#对象类型判断" class="headerlink" title="对象类型判断"></a>对象类型判断</h1><h2 id="数组-1"><a href="#数组-1" class="headerlink" title="数组"></a>数组</h2><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
arr <span class="token keyword">instanceof</span> <span class="token class-name">Array</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token class-name">Object</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// "[object Array]"</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="js-单线程,如何异步"><a href="#js-单线程,如何异步" class="headerlink" title="js 单线程,如何异步"></a>js 单线程,如何异步</h1><ul>
<li><p>主线程 执行 js 中所有的代码。</p>
</li>
<li><p>主线程 在执行过程中发现了需要异步的任务任务后扔给浏览器(浏览器创建多个线程执行,顺便创造一个<code>回调队列</code></p>
</li>
<li><p>主线程 已经执行完毕所有同步代码。监听<code>回调队列</code>一旦 浏览器 中某个线程任务完成将会改变回调函数的状态。主线程查看到某个函数的状态为已完成,就会执行该<code>回调队列</code>中对应的回调函数。</p>
</li>
</ul>
<h1 id="移动端最小触控区域"><a href="#移动端最小触控区域" class="headerlink" title="移动端最小触控区域"></a>移动端最小触控区域</h1><p>苹果推荐是 44pt x 44pt 「具体看 WWDC 14」,通过<code>padding</code><code>margin</code><code>height</code>等方式进行点击区域扩展</p>
<h1 id="js-精度问题"><a href="#js-精度问题" class="headerlink" title="js 精度问题"></a>js 精度问题</h1><p>常用类库:<code>Math.js</code><code>Big.js</code><code>decimal.js</code></p>
<h1 id="冻结-Object-freeze"><a href="#冻结-Object-freeze" class="headerlink" title="冻结 Object. freeze()"></a>冻结 Object. freeze()</h1><p><code>const</code>生命的简单变量不可修改,但是复杂对象可以被修改,<code>Object. freeze()</code>:可以冻结对象</p>
<ul>
<li>不能添加新属性</li>
<li>不能删除已有属性</li>
<li>不能修改已有属性的可枚举性、可配置性、可写性</li>
<li>不能修改已有属性的值</li>
<li>不能修改原型</li>
</ul>
<p>浅冻结</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">const</span> obj1 <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
<span class="token literal-property property">internal</span><span class="token operator">:</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
Object<span class="token punctuation">.</span><span class="token function">freeze</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">;</span>
obj1<span class="token punctuation">.</span>internal<span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token string">"aValue"</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj1<span class="token punctuation">.</span>internal<span class="token punctuation">.</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// aValue</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>递归冻结</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">deepFreeze</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token comment">// 获取定义在obj上的属性名</span>
<span class="token keyword">var</span> propNames <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">getOwnPropertyNames</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 在冻结自身之前冻结属性</span>
propNames<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">var</span> prop <span class="token operator">=</span> obj<span class="token punctuation">[</span>name<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token comment">// 如果prop是个对象冻结它</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> prop <span class="token operator">==</span> <span class="token string">"object"</span> <span class="token operator">&amp;&amp;</span> prop <span class="token operator">!==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token function">deepFreeze</span><span class="token punctuation">(</span>prop<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> Object<span class="token punctuation">.</span><span class="token function">freeze</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="Reflect"><a href="#Reflect" class="headerlink" title="Reflect"></a>Reflect</h1><h2 id="Reflect-get-target-propertyKey-value-receiver"><a href="#Reflect-get-target-propertyKey-value-receiver" class="headerlink" title="Reflect.get(target, propertyKey, value[receiver])"></a>Reflect.get(target, propertyKey, value[receiver])</h2><p>获取对象身上某个属性的值,类似于 target[name]。</p>
<h2 id="Reflect-set-target-propertyKey-value-receiver"><a href="#Reflect-set-target-propertyKey-value-receiver" class="headerlink" title="Reflect.set(target, propertyKey, value[receiver])"></a>Reflect.set(target, propertyKey, value[receiver])</h2><p>将值分配给属性的函数。返回一个 Boolean如果更新成功则返回 true。</p>
<h2 id="Reflect-has-target-propertyKey"><a href="#Reflect-has-target-propertyKey" class="headerlink" title="Reflect.has(target, propertyKey)"></a>Reflect.has(target, propertyKey)</h2><p>判断一个对象是否存在某个属性,和 in 运算符 的功能完全相同。</p>
<h1 id="if-else-优化"><a href="#if-else-优化" class="headerlink" title="if else 优化"></a>if else 优化</h1><h2 id="表驱动编程"><a href="#表驱动编程" class="headerlink" title="表驱动编程"></a>表驱动编程</h2><p>空间换时间,设置<code>obj=&#123;key:value&#125;</code>,通过<code>obj[key]</code>取值</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token function">calculateGrade</span><span class="token punctuation">(</span><span class="token parameter">score</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
<span class="token keyword">const</span> table <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
<span class="token number">100</span><span class="token operator">:</span> <span class="token string">'A'</span><span class="token punctuation">,</span>
<span class="token number">90</span><span class="token operator">:</span> <span class="token string">'A'</span><span class="token punctuation">,</span>
<span class="token number">80</span><span class="token operator">:</span> <span class="token string">'B'</span><span class="token punctuation">,</span>
<span class="token number">70</span><span class="token operator">:</span> <span class="token string">'C'</span><span class="token punctuation">,</span>
<span class="token number">60</span><span class="token operator">:</span> <span class="token string">'D'</span><span class="token punctuation">,</span>
<span class="token literal-property property">others</span><span class="token operator">:</span> <span class="token string">'E'</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">return</span> table<span class="token punctuation">[</span>Math<span class="token punctuation">.</span><span class="token function">floor</span><span class="token punctuation">(</span>score<span class="token operator">/</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token operator">*</span><span class="token number">10</span><span class="token punctuation">]</span> <span class="token operator">||</span> table<span class="token punctuation">[</span><span class="token string">'others'</span><span class="token punctuation">]</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="短路运算"><a href="#短路运算" class="headerlink" title="短路运算"></a>短路运算</h2><p>react 没有<code>v-if</code>,运用比较频繁</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">// 函数组件</span>
<span class="token keyword">const</span> <span class="token function-variable function">Home</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token operator">&lt;</span>div<span class="token operator">></span>home<span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token punctuation">&#123;</span>
<span class="token boolean">true</span> <span class="token operator">&amp;&amp;</span> <span class="token operator">&lt;</span>Home <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="使用有意义且易读的变量名"><a href="#使用有意义且易读的变量名" class="headerlink" title="使用有意义且易读的变量名"></a>使用有意义且易读的变量名</h1><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">👎 <span class="token keyword">const</span> yyyymmdstr <span class="token operator">=</span> <span class="token function">moment</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"YYYY/MM/DD"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
👍 <span class="token keyword">const</span> currentDate <span class="token operator">=</span> <span class="token function">moment</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string">"YYYY/MM/DD"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<h1 id="使用有意义的变量代替数组下标"><a href="#使用有意义的变量代替数组下标" class="headerlink" title="使用有意义的变量代替数组下标"></a>使用有意义的变量代替数组下标</h1><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">👎
<span class="token keyword">const</span> address <span class="token operator">=</span> <span class="token string">"One Infinite Loop, Cupertino 95014"</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> cityZipCodeRegex <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^[^,\\]+[,\\\s]+(.+?)\s*(\d&#123;5&#125;)?$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span>
<span class="token function">saveCityZipCode</span><span class="token punctuation">(</span>
address<span class="token punctuation">.</span><span class="token function">match</span><span class="token punctuation">(</span>cityZipCodeRegex<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
address<span class="token punctuation">.</span><span class="token function">match</span><span class="token punctuation">(</span>cityZipCodeRegex<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
👍
<span class="token keyword">const</span> address <span class="token operator">=</span> <span class="token string">"One Infinite Loop, Cupertino 95014"</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> cityZipCodeRegex <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">^[^,\\]+[,\\\s]+(.+?)\s*(\d&#123;5&#125;)?$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token punctuation">[</span>_<span class="token punctuation">,</span> city<span class="token punctuation">,</span> zipCode<span class="token punctuation">]</span> <span class="token operator">=</span> address<span class="token punctuation">.</span><span class="token function">match</span><span class="token punctuation">(</span>cityZipCodeRegex<span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token function">saveCityZipCode</span><span class="token punctuation">(</span>city<span class="token punctuation">,</span> zipCode<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="变量名要简洁"><a href="#变量名要简洁" class="headerlink" title="变量名要简洁"></a>变量名要简洁</h1><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">👎
<span class="token keyword">const</span> Car <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
<span class="token literal-property property">carMake</span><span class="token operator">:</span> <span class="token string">"Honda"</span><span class="token punctuation">,</span>
<span class="token literal-property property">carModel</span><span class="token operator">:</span> <span class="token string">"Accord"</span><span class="token punctuation">,</span>
<span class="token literal-property property">carColor</span><span class="token operator">:</span> <span class="token string">"Blue"</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token keyword">function</span> <span class="token function">paintCar</span><span class="token punctuation">(</span><span class="token parameter">car<span class="token punctuation">,</span> color</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
car<span class="token punctuation">.</span>carColor <span class="token operator">=</span> color<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
👍
<span class="token keyword">const</span> Car <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
<span class="token literal-property property">make</span><span class="token operator">:</span> <span class="token string">"Honda"</span><span class="token punctuation">,</span>
<span class="token literal-property property">model</span><span class="token operator">:</span> <span class="token string">"Accord"</span><span class="token punctuation">,</span>
<span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token string">"Blue"</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token keyword">function</span> <span class="token function">paintCar</span><span class="token punctuation">(</span><span class="token parameter">car<span class="token punctuation">,</span> color</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
car<span class="token punctuation">.</span>color <span class="token operator">=</span> color<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="消除魔术字符串"><a href="#消除魔术字符串" class="headerlink" title="消除魔术字符串"></a>消除魔术字符串</h1><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">👎 <span class="token function">setTimeout</span><span class="token punctuation">(</span>blastOff<span class="token punctuation">,</span> <span class="token number">86400000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
👍 <span class="token keyword">const</span> <span class="token constant">MILLISECONDS_PER_DAY</span> <span class="token operator">=</span> <span class="token number">60</span> <span class="token operator">*</span> <span class="token number">60</span> <span class="token operator">*</span> <span class="token number">24</span> <span class="token operator">*</span> <span class="token number">1000</span><span class="token punctuation">;</span> <span class="token comment">//86400000;</span>
<span class="token function">setTimeout</span><span class="token punctuation">(</span>blastOff<span class="token punctuation">,</span> <span class="token constant">MILLISECONDS_PER_DAY</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="使用默认参数替代短路运算符"><a href="#使用默认参数替代短路运算符" class="headerlink" title="使用默认参数替代短路运算符"></a>使用默认参数替代短路运算符</h1><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">👎
<span class="token keyword">function</span> <span class="token function">createMicrobrewery</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">const</span> breweryName <span class="token operator">=</span> name <span class="token operator">||</span> <span class="token string">"Hipster Brew Co."</span><span class="token punctuation">;</span>
<span class="token comment">// ...</span>
<span class="token punctuation">&#125;</span>
👍
<span class="token keyword">function</span> <span class="token function">createMicrobrewery</span><span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token string">"Hipster Brew Co."</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token comment">// ...</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="一个函数"><a href="#一个函数" class="headerlink" title="一个函数"></a>一个函数</h1><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">👎
<span class="token keyword">function</span> <span class="token function">emailClients</span><span class="token punctuation">(</span><span class="token parameter">clients</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
clients<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token parameter">client</span> <span class="token operator">=></span> <span class="token punctuation">&#123;</span>
<span class="token keyword">const</span> clientRecord <span class="token operator">=</span> database<span class="token punctuation">.</span><span class="token function">lookup</span><span class="token punctuation">(</span>client<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>clientRecord<span class="token punctuation">.</span><span class="token function">isActive</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token function">email</span><span class="token punctuation">(</span>client<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
👍
<span class="token keyword">function</span> <span class="token function">emailActiveClients</span><span class="token punctuation">(</span><span class="token parameter">clients</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
clients<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span>isActiveClient<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>email<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">function</span> <span class="token function">isActiveClient</span><span class="token punctuation">(</span><span class="token parameter">client</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">const</span> clientRecord <span class="token operator">=</span> database<span class="token punctuation">.</span><span class="token function">lookup</span><span class="token punctuation">(</span>client<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> clientRecord<span class="token punctuation">.</span><span class="token function">isActive</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-</span>分割线<span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-</span>
👎
<span class="token keyword">function</span> <span class="token function">createFile</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> temp</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>temp<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
fs<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">./temp/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>name<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
fs<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
👍
<span class="token keyword">function</span> <span class="token function">createFile</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
fs<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">function</span> <span class="token function">createTempFile</span><span class="token punctuation">(</span><span class="token parameter">name</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token function">createFile</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">./temp/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>name<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="函数参数不多于-2-个,如果有很多参数就利用-object-传递,并使用解构"><a href="#函数参数不多于-2-个,如果有很多参数就利用-object-传递,并使用解构" class="headerlink" title="函数参数不多于 2 个,如果有很多参数就利用 object 传递,并使用解构"></a>函数参数不多于 2 个,如果有很多参数就利用 object 传递,并使用解构</h1><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">👎
<span class="token keyword">function</span> <span class="token function">createMenu</span><span class="token punctuation">(</span><span class="token parameter">title<span class="token punctuation">,</span> body<span class="token punctuation">,</span> buttonText<span class="token punctuation">,</span> cancellable</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token comment">// ...</span>
<span class="token punctuation">&#125;</span>
<span class="token function">createMenu</span><span class="token punctuation">(</span><span class="token string">"Foo"</span><span class="token punctuation">,</span> <span class="token string">"Bar"</span><span class="token punctuation">,</span> <span class="token string">"Baz"</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
👍
<span class="token keyword">function</span> <span class="token function">createMenu</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">&#123;</span> title<span class="token punctuation">,</span> body<span class="token punctuation">,</span> buttonText<span class="token punctuation">,</span> cancellable <span class="token punctuation">&#125;</span></span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token comment">// ...</span>
<span class="token punctuation">&#125;</span>
<span class="token function">createMenu</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
<span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">"Foo"</span><span class="token punctuation">,</span>
<span class="token literal-property property">body</span><span class="token operator">:</span> <span class="token string">"Bar"</span><span class="token punctuation">,</span>
<span class="token literal-property property">buttonText</span><span class="token operator">:</span> <span class="token string">"Baz"</span><span class="token punctuation">,</span>
<span class="token literal-property property">cancellable</span><span class="token operator">:</span> <span class="token boolean">true</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="函数名应该直接反映函数的作用"><a href="#函数名应该直接反映函数的作用" class="headerlink" title="函数名应该直接反映函数的作用"></a>函数名应该直接反映函数的作用</h1><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">👎
<span class="token keyword">function</span> <span class="token function">addToDate</span><span class="token punctuation">(</span><span class="token parameter">date<span class="token punctuation">,</span> month</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token comment">// ...</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">const</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// It's hard to tell from the function name what is added</span>
<span class="token function">addToDate</span><span class="token punctuation">(</span>date<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
👍
<span class="token keyword">function</span> <span class="token function">addMonthToDate</span><span class="token punctuation">(</span><span class="token parameter">month<span class="token punctuation">,</span> date</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token comment">// ...</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">const</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">addMonthToDate</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> date<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="尽量使用纯函数"><a href="#尽量使用纯函数" class="headerlink" title="尽量使用纯函数"></a>尽量使用纯函数</h1><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">👎
<span class="token keyword">const</span> programmerOutput <span class="token operator">=</span> <span class="token punctuation">[</span>
<span class="token punctuation">&#123;</span>
<span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Uncle Bobby"</span><span class="token punctuation">,</span>
<span class="token literal-property property">linesOfCode</span><span class="token operator">:</span> <span class="token number">500</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#123;</span>
<span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Suzie Q"</span><span class="token punctuation">,</span>
<span class="token literal-property property">linesOfCode</span><span class="token operator">:</span> <span class="token number">1500</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#123;</span>
<span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Jimmy Gosling"</span><span class="token punctuation">,</span>
<span class="token literal-property property">linesOfCode</span><span class="token operator">:</span> <span class="token number">150</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#123;</span>
<span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Gracie Hopper"</span><span class="token punctuation">,</span>
<span class="token literal-property property">linesOfCode</span><span class="token operator">:</span> <span class="token number">1000</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> totalOutput <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> programmerOutput<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
totalOutput <span class="token operator">+=</span> programmerOutput<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>linesOfCode<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
👍
<span class="token keyword">const</span> programmerOutput <span class="token operator">=</span> <span class="token punctuation">[</span>
<span class="token punctuation">&#123;</span>
<span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Uncle Bobby"</span><span class="token punctuation">,</span>
<span class="token literal-property property">linesOfCode</span><span class="token operator">:</span> <span class="token number">500</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#123;</span>
<span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Suzie Q"</span><span class="token punctuation">,</span>
<span class="token literal-property property">linesOfCode</span><span class="token operator">:</span> <span class="token number">1500</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#123;</span>
<span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Jimmy Gosling"</span><span class="token punctuation">,</span>
<span class="token literal-property property">linesOfCode</span><span class="token operator">:</span> <span class="token number">150</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#123;</span>
<span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">"Gracie Hopper"</span><span class="token punctuation">,</span>
<span class="token literal-property property">linesOfCode</span><span class="token operator">:</span> <span class="token number">1000</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> totalOutput <span class="token operator">=</span> programmerOutput<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span>
<span class="token punctuation">(</span><span class="token parameter">totalLines<span class="token punctuation">,</span> output</span><span class="token punctuation">)</span> <span class="token operator">=></span> totalLines <span class="token operator">+</span> output<span class="token punctuation">.</span>linesOfCode<span class="token punctuation">,</span>
<span class="token number">0</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="不要过度优化"><a href="#不要过度优化" class="headerlink" title="不要过度优化"></a>不要过度优化</h1><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">👎
<span class="token comment">// 现代浏览器对于迭代器做了内部优化</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> len <span class="token operator">=</span> list<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i <span class="token operator">&lt;</span> len<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token comment">// ...</span>
<span class="token punctuation">&#125;</span>
👍
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> list<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token comment">// ...</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="关于模块化"><a href="#关于模块化" class="headerlink" title="关于模块化"></a>关于模块化</h1><h2 id="无模块化"><a href="#无模块化" class="headerlink" title="无模块化"></a>无模块化</h2><blockquote>
<p>污染全局作用域、维护成本高、依赖关系不明显</p>
</blockquote>
<p>script 标签引入 js 文件,相互罗列,但是被依赖的放在前面,否则使用就会报错。如下:</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"jquery.js"</span><span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">></span>
<span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"main.js"</span><span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">></span>
<span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"other1.js"</span><span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">></span>
<span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"other2.js"</span><span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">></span>
<span class="token operator">&lt;</span>script src<span class="token operator">=</span><span class="token string">"other3.js"</span><span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="CommonJS-规范-同步"><a href="#CommonJS-规范-同步" class="headerlink" title="CommonJS 规范(同步)"></a>CommonJS 规范(同步)</h2><p>该规范最初是用在服务器端的 node 的它有四个重要的环境变量为模块化的实现提供支持module、exports、require、global。实际使用时用 module.exports 定义当前模块对外输出的接口(不推荐直接用 exports用 require 加载模块(同步)</p>
<blockquote>
<p>module.exports 本身就是一个对象</p>
</blockquote>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">&#123;</span> <span class="token literal-property property">foo</span><span class="token operator">:</span> <span class="token string">"bar"</span> <span class="token punctuation">&#125;</span><span class="token punctuation">;</span> <span class="token comment">//true</span>
module<span class="token punctuation">.</span>exports<span class="token punctuation">.</span>foo <span class="token operator">=</span> <span class="token string">"bar"</span><span class="token punctuation">;</span> <span class="token comment">//true。</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<p>CommonJS 用同步的方式加载模块。在服务端模块文件都存在本地磁盘读取非常快所以这样做不会有问题。但是在浏览器端限于网络原因CommonJS 不适合浏览器端模块加载,更合理的方案是使用异步加载,比如下边 AMD 规范。</p>
<h2 id="AMD-规范-RequireJS"><a href="#AMD-规范-RequireJS" class="headerlink" title="AMD 规范(RequireJS)"></a>AMD 规范(RequireJS)</h2><p>承接上文AMD 规范则是非同步加载模块允许指定回调函数AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。</p>
<ul>
<li><code>require([module], callback)</code>:加载模块</li>
<li><code>define(id, [depends], callback)</code>:定义模块</li>
<li><code>require.config()</code>:配置路径、依赖关系</li>
</ul>
<h2 id="CMD-规范-SeaJS"><a href="#CMD-规范-SeaJS" class="headerlink" title="CMD 规范(SeaJS)"></a>CMD 规范(SeaJS)</h2><p>CMD 是 在推广过程中对模块定义的规范化产出</p>
<h2 id="ES6-import-x2F-export"><a href="#ES6-import-x2F-export" class="headerlink" title="ES6 import&#x2F;export"></a>ES6 import&#x2F;export</h2><p>通过 babel 将不被支持的 import 编译为当前受到广泛支持的 AMD 规范</p>
<h1 id="AMD模块化实现"><a href="#AMD模块化实现" class="headerlink" title="AMD模块化实现"></a>AMD模块化实现</h1><h2 id="define-函数"><a href="#define-函数" class="headerlink" title="define 函数"></a>define 函数</h2><p>用来声明模块名<code>module</code>,依赖数组<code>deps</code>,以及模块的作用<code>callback</code></p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> module <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">var</span> stack <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span> <span class="token comment">//模块存储栈,存的是模块执行后的结果</span>
<span class="token keyword">function</span> <span class="token function">define</span><span class="token punctuation">(</span><span class="token parameter">module<span class="token punctuation">,</span> deps<span class="token punctuation">,</span> callback</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
stack<span class="token punctuation">[</span>module<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">callback</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> deps<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 压栈</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>stack<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 查看栈存储的模块</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">return</span> <span class="token punctuation">&#123;</span> <span class="token literal-property property">define</span><span class="token operator">:</span> define <span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>调用<code>define</code>试试,发现 <code>calc</code>模块被压入了<code>stack 模块栈中</code></p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">module<span class="token punctuation">.</span><span class="token function">define</span><span class="token punctuation">(</span><span class="token string">"calc"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token punctuation">&#123;</span>
<span class="token function-variable function">first</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// &#123;calc: &#123; first: ƒ &#125;&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="deps-依赖-导入"><a href="#deps-依赖-导入" class="headerlink" title="deps 依赖(导入)"></a>deps 依赖(导入)</h2><p>对上面的 <code>define</code>函数稍加改造,这一步过程的本质,就是对 deps</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">var</span> module <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">window</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">var</span> stack <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span> <span class="token comment">//模块存储栈,</span>
<span class="token keyword">function</span> <span class="token function">define</span><span class="token punctuation">(</span><span class="token parameter">module<span class="token punctuation">,</span> deps<span class="token punctuation">,</span> callback</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token comment">// 把 define 函数依赖数组中的模块从 stack 模块中拿出</span>
deps<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">mod<span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
deps<span class="token punctuation">[</span>index<span class="token punctuation">]</span> <span class="token operator">=</span> stack<span class="token punctuation">[</span>mod<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// 赋值给当前模块的 deps</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
stack<span class="token punctuation">[</span>module<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">callback</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> deps<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>stack<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 查看栈存储的模块</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">return</span> <span class="token punctuation">&#123;</span> <span class="token literal-property property">define</span><span class="token operator">:</span> define <span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">(</span>window<span class="token punctuation">)</span><span class="token punctuation">;</span>
module<span class="token punctuation">.</span><span class="token function">define</span><span class="token punctuation">(</span><span class="token string">"calc"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token punctuation">&#123;</span>
<span class="token function-variable function">first</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> arr<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
module<span class="token punctuation">.</span><span class="token function">define</span><span class="token punctuation">(</span><span class="token string">"number"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"calc"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">calc</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token punctuation">&#123;</span>
<span class="token literal-property property">res</span><span class="token operator">:</span> calc<span class="token punctuation">.</span><span class="token function">first</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">//4</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 此时 stack 打印的结果为</span>
<span class="token comment">//> calc: &#123;first: ƒ&#125;</span>
<span class="token comment">//> number: &#123;res: 4&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<blockquote>
<p>从本质上看define 函数的第二个参数 deps 数组,相当于 import 导入,并且如果第三个参数 callback 采用 <code>return &#123; &#125;</code>,也就相当于 export 导出</p>
</blockquote>
<h2 id="老生常谈的指针"><a href="#老生常谈的指针" class="headerlink" title="老生常谈的指针"></a>老生常谈的指针</h2><p>说到底,<code>stack</code><code>a模块</code> export 是一个指针,<code>&#123;a:value&#125;</code>(内存地址),所以,<code>b 模块</code>会改变<code>a.a</code>的值,这点和 <code>cmd</code>不同</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript">module<span class="token punctuation">.</span><span class="token function">define</span><span class="token punctuation">(</span><span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token punctuation">&#123;</span>
<span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
module<span class="token punctuation">.</span><span class="token function">define</span><span class="token punctuation">(</span><span class="token string">"b"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">a</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
a<span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
module<span class="token punctuation">.</span><span class="token function">define</span><span class="token punctuation">(</span><span class="token string">"c"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">"a"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">a</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>a<span class="token punctuation">.</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="缘起-Object-defineProperty"><a href="#缘起-Object-defineProperty" class="headerlink" title="缘起 Object.defineProperty()"></a>缘起 Object.defineProperty()</h1><p><code>目标对象</code>上定义一个新属性,或者修改<code>目标对象</code>属性,并且返回新对象</p>
<h1 id="上帝的钥匙-get-amp-set"><a href="#上帝的钥匙-get-amp-set" class="headerlink" title="上帝的钥匙 get &amp; set"></a>上帝的钥匙 get &amp; set</h1><p>属性的<code>getter</code>函数,如果没有 <code>getter</code>则尾 <code>undefined</code>。当访问该属性时,会调用此函数.</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token punctuation">&#123;</span>
<span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token number">7</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token function">set</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">FAILED改变 a 属性,新值为:</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>val<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">,但是被重写 set 劫持了</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span>
obj<span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<blockquote>
<p>上帝的钥匙被找到了</p>
</blockquote>
<p>劫持!劫持!还是 TMD 劫持!</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> tempValue <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token punctuation">&#123;</span>
<span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> tempValue<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token function">set</span><span class="token punctuation">(</span>newValue<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
tempValue <span class="token operator">=</span> newValue<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span>
obj<span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 4</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="封装-defineReactive-obj-prop-val"><a href="#封装-defineReactive-obj-prop-val" class="headerlink" title="封装 defineReactive(obj, prop, val)"></a>封装 defineReactive(obj, prop, val)</h1><blockquote>
<p>这里 defineReactive 第三个参数 val 替代了上一步中全局变量<code>tempValue</code>,对于 get()、set()来说,访问到了其他函数内部的变量,所以形成了闭包</p>
</blockquote>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">defineReactive</span><span class="token punctuation">(</span><span class="token parameter">obj<span class="token punctuation">,</span> prop<span class="token punctuation">,</span> val</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token punctuation">&#123;</span>
<span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">劫持,你访问了</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>prop<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">属性</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> val<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token function">set</span><span class="token punctuation">(</span>newValue<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>val <span class="token operator">===</span> newValue<span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">劫持,你改变了</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>prop<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">属性</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
val <span class="token operator">=</span> newValue<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token function">defineReactive</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 劫持你访问了a属性 4</span>
obj<span class="token punctuation">.</span>a <span class="token operator">=</span> <span class="token number">7</span><span class="token punctuation">;</span> <span class="token comment">// 劫持你改变了a属性</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 劫持你访问了a属性 7</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="递归侦测"><a href="#递归侦测" class="headerlink" title="递归侦测"></a>递归侦测</h1><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">&#123;</span> <span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token punctuation">&#123;</span> <span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token punctuation">&#123;</span> <span class="token literal-property property">c</span><span class="token operator">:</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span> <span class="token punctuation">&#125;</span> <span class="token punctuation">&#125;</span> <span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
<span class="token function">defineReactive</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> <span class="token string">"a"</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<blockquote>
<p>如何自动让<code>obj</code>对象的全部属性都<code>reactive</code>呢?</p>
</blockquote>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">&#123;</span>
<span class="token literal-property property">a</span><span class="token operator">:</span> <span class="token punctuation">&#123;</span>
<span class="token literal-property property">b</span><span class="token operator">:</span> <span class="token punctuation">&#123;</span>
<span class="token literal-property property">c</span><span class="token operator">:</span> <span class="token number">5</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token literal-property property">d</span><span class="token operator">:</span> <span class="token number">4</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>定义个方法<code>observe</code>,递归 <code>obj</code> 的每一层的每个 <code>prop</code>,检测是否有<code>__ob__</code>,如果没有,<code>defineReactive</code>,并且挂一个<code>Observer</code>实例在这个<code>props</code>上,例如:</p>
<p><code>Observer对象</code></p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">class</span> <span class="token class-name">Observer</span> <span class="token punctuation">&#123;</span>
<span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token function">def</span><span class="token punctuation">(</span>value<span class="token punctuation">,</span> <span class="token string">"__ob__"</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 不可枚举不能给__ob__添加__ob__</span>
<span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">walk</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// 遍历每一个 prop的 value</span>
<span class="token function">walk</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> prop <span class="token keyword">in</span> value<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token function">defineReactive</span><span class="token punctuation">(</span>value<span class="token punctuation">,</span> prop<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p><code>defineReactive.js</code></p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">defineReactive</span><span class="token punctuation">(</span><span class="token parameter">obj<span class="token punctuation">,</span> prop<span class="token punctuation">,</span> val</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>arguments<span class="token punctuation">.</span>length <span class="token operator">===</span> <span class="token number">2</span><span class="token punctuation">)</span> val <span class="token operator">=</span> obj<span class="token punctuation">[</span>prop<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// 如果2个参数</span>
<span class="token keyword">let</span> childNode <span class="token operator">=</span> <span class="token function">observe</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>
Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span> prop<span class="token punctuation">,</span> <span class="token punctuation">&#123;</span>
<span class="token literal-property property">enumerable</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
<span class="token literal-property property">configurable</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
<span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">你访问了</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>prop<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">属性</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> val<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token function">set</span><span class="token punctuation">(</span>newValue<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>val <span class="token operator">===</span> newValue<span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">你改变了</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">$&#123;</span>prop<span class="token interpolation-punctuation punctuation">&#125;</span></span><span class="token string">属性</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
val <span class="token operator">=</span> newValue<span class="token punctuation">;</span>
childNode <span class="token operator">=</span> <span class="token function">observe</span><span class="token punctuation">(</span>newValue<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p><code>observe.js</code></p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token comment">/**
* 检测 obj 身上有没有 __ob__(Observer 实例)
* @param &#123;*&#125; value
* @returns
*/</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">observe</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> value <span class="token operator">!=</span> <span class="token string">"object"</span><span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> ob<span class="token punctuation">;</span>
<span class="token comment">//! 用__ob__是为了属性不重名被覆盖</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> value<span class="token punctuation">.</span>__ob__ <span class="token operator">!=</span> <span class="token string">"undefined"</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
ob <span class="token operator">=</span> value<span class="token punctuation">.</span>__ob__<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
ob <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Observer</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">return</span> ob<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<div class="post-tags">
<!-- 文章tags -->
</div>
<p class="motto">重拾纯粹的写作</p>
</article>
<!-- 评论 -->
<div id="vcomments"></div>
</div>
</main>
<!-- toc -->
<cosy-drag-box id="toc-drag-box" trigger="left" min-width="220" uid="toc-box">
<div class="meta-container">
<div class="toc-wrapper cosy-scrollbar">
<cosy-tooltip placement="right">
<p class="catalog">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24">
<g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 6h16"></path>
<path d="M4 12h16"></path>
<path d="M4 18h12"></path>
</g>
</svg>
<span>目录</span>
</p>
<span slot="content">
<span>隐藏目录</span>
<cosy-short-key>]</cosy-short-key>
</span>
</cosy-tooltip>
<!-- 文章toc -->
<ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%A8%A1%E6%9D%BF%E5%BC%95%E6%93%8E"><span class="toc-number">1.</span> <span class="toc-text">模板引擎</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%8F%A4%E8%80%81%E6%95%B0%E6%8D%AE%E6%B8%B2%E6%9F%93-vm-%E7%9A%84%E6%96%B9%E5%BC%8F"><span class="toc-number">2.</span> <span class="toc-text">古老数据渲染 vm 的方式</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#mustache-%E5%8E%9F%E7%90%86"><span class="toc-number">3.</span> <span class="toc-text">mustache 原理</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#tokens-%E7%94%9F%E6%88%90%E7%AE%97%E6%B3%95"><span class="toc-number">3.1.</span> <span class="toc-text">tokens 生成算法</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%A0%88%E9%98%9F%E5%88%97%E7%AE%97%E6%B3%95"><span class="toc-number">3.2.</span> <span class="toc-text">栈队列算法</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%B8%B8%E7%94%A8%E5%B7%A5%E5%85%B7%E7%B1%BB"><span class="toc-number">4.</span> <span class="toc-text">常用工具类</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%80%92%E5%BD%92"><span class="toc-number">4.1.</span> <span class="toc-text">递归</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%87%AA%E5%A2%9Eid%E7%9F%AD%E7%A0%81"><span class="toc-number">4.2.</span> <span class="toc-text">自增id短码</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%89%8B%E5%8A%A8%E5%AE%9E%E7%8E%B0-eventBus"><span class="toc-number">4.3.</span> <span class="toc-text">手动实现 eventBus</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%88%A4%E6%96%AD%E5%AF%B9%E8%B1%A1%E6%98%AF%E5%90%A6%E6%9C%89%E6%9F%90%E4%B8%AA-key"><span class="toc-number">4.4.</span> <span class="toc-text">判断对象是否有某个 key</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%B5%8F%E8%A7%88%E5%99%A8"><span class="toc-number">4.5.</span> <span class="toc-text">浏览器</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%89%88%E6%9C%AC%E4%BF%A1%E6%81%AF"><span class="toc-number">4.6.</span> <span class="toc-text">版本信息</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%BC%E5%AE%B9%E4%BA%8B%E4%BB%B6%E7%BB%91%E5%AE%9A"><span class="toc-number">4.7.</span> <span class="toc-text">兼容事件绑定</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%95%B0%E7%BB%84%E5%AF%B9%E8%B1%A1"><span class="toc-number">4.8.</span> <span class="toc-text">数组对象</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#reduce"><span class="toc-number">4.9.</span> <span class="toc-text">reduce</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AF%B9%E8%B1%A1%E5%86%85%E9%83%A8%E6%A0%B9%E6%8D%AE-key-%E5%AF%B9-value-%E8%BF%9B%E8%A1%8C%E6%8E%92%E5%BA%8F-%E5%8F%96%E5%89%8D-3"><span class="toc-number">4.10.</span> <span class="toc-text">对象内部根据 key 对 value 进行排序,取前 3</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%9A%8F%E6%9C%BA%E5%AD%97%E7%AC%A6%E4%B8%B2"><span class="toc-number">4.11.</span> <span class="toc-text">随机字符串</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%B1%BB%E5%9E%8B%E6%A3%80%E6%B5%8B"><span class="toc-number">4.12.</span> <span class="toc-text">类型检测</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%80%92%E8%AE%A1%E6%97%B6"><span class="toc-number">4.13.</span> <span class="toc-text">倒计时</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%8C%83%E5%9B%B4%E9%9A%8F%E6%9C%BA%E6%95%B0"><span class="toc-number">4.14.</span> <span class="toc-text">范围随机数</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%8E%B7%E5%8F%96%E5%BD%93%E5%89%8D%E6%9C%88%E7%9A%84%E5%A4%A9%E6%95%B0"><span class="toc-number">4.15.</span> <span class="toc-text">获取当前月的天数</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%AF%B9%E8%B1%A1%E5%B0%8F%E6%93%8D%E4%BD%9C"><span class="toc-number">5.</span> <span class="toc-text">对象小操作</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8E%BB%E8%99%9A%E5%81%87%E5%80%BC"><span class="toc-number">5.1.</span> <span class="toc-text">去虚假值</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%A4%B4%E5%B0%BE%E6%8F%92%E5%85%A5"><span class="toc-number">5.2.</span> <span class="toc-text">头尾插入</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%88%A0%E9%99%A4%E5%B1%9E%E6%80%A7"><span class="toc-number">5.3.</span> <span class="toc-text">删除属性</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E7%94%9F%E4%BA%A7%E3%80%81%E5%8A%A0%E5%B7%A5%E3%80%81%E6%B6%88%E8%B4%B9%E5%88%86%E7%A6%BB"><span class="toc-number">6.</span> <span class="toc-text">生产、加工、消费分离</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%85%83%E6%95%B0%E6%8D%AE"><span class="toc-number">7.</span> <span class="toc-text">元数据</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E9%98%B2%E6%8A%96%E4%B8%8E%E8%8A%82%E6%B5%81"><span class="toc-number">8.</span> <span class="toc-text">防抖与节流</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#Debounce"><span class="toc-number">8.1.</span> <span class="toc-text">Debounce</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Throttle"><span class="toc-number">8.2.</span> <span class="toc-text">Throttle</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#this-%E6%8C%87%E5%90%91"><span class="toc-number">9.</span> <span class="toc-text">this 指向</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%A8%E5%B1%80%E7%8E%AF%E5%A2%83"><span class="toc-number">9.1.</span> <span class="toc-text">全局环境</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E4%B8%8A%E4%B8%8B%E6%96%87%E8%B0%83%E7%94%A8"><span class="toc-number">9.2.</span> <span class="toc-text">函数上下文调用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0"><span class="toc-number">9.3.</span> <span class="toc-text">箭头函数</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#call-apply-bind-%E4%B8%8E-es6"><span class="toc-number">10.</span> <span class="toc-text">call, apply, bind 与 es6</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#for-%E5%BE%AA%E7%8E%AF%E4%BC%98%E5%8C%96"><span class="toc-number">11.</span> <span class="toc-text">for 循环优化</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%95%B0%E7%BB%84"><span class="toc-number">12.</span> <span class="toc-text">数组</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%89%81%E5%B9%B3%E5%8C%96%E5%8E%BB%E9%87%8D%E5%8D%87%E5%BA%8F%E6%8E%92%E5%88%97"><span class="toc-number">12.1.</span> <span class="toc-text">扁平化去重升序排列</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%89%8D%E7%AB%AF%E9%A1%B5%E9%9D%A2%E5%9F%8B%E7%82%B9-1x1-gif"><span class="toc-number">13.</span> <span class="toc-text">前端页面埋点 - 1x1.gif</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E4%BA%8B%E4%BB%B6%E5%A7%94%E6%89%98"><span class="toc-number">14.</span> <span class="toc-text">事件委托</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0-%E5%8E%9F%E5%9E%8B%E6%A8%A1%E5%BC%8F"><span class="toc-number">15.</span> <span class="toc-text">构造函数 + 原型模式</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%89%A9%E4%BD%99%E5%8F%82%E6%95%B0%E2%80%A6args"><span class="toc-number">16.</span> <span class="toc-text">剩余参数…args</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E8%B7%A8%E9%A1%B5%E9%9D%A2%E9%80%9A%E4%BF%A1"><span class="toc-number">17.</span> <span class="toc-text">跨页面通信</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#iframe-%E8%B7%A8%E5%9F%9F%E9%80%9A%E4%BF%A1%E5%92%8C%E4%B8%8D%E8%B7%A8%E5%9F%9F%E9%80%9A%E4%BF%A1"><span class="toc-number">18.</span> <span class="toc-text">iframe 跨域通信和不跨域通信</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%8D%E8%B7%A8%E5%9F%9F"><span class="toc-number">18.1.</span> <span class="toc-text">不跨域</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%B7%A8%E5%9F%9F-postMessage"><span class="toc-number">18.2.</span> <span class="toc-text">跨域 postMessage</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%AF%B9%E8%B1%A1%E7%B1%BB%E5%9E%8B%E5%88%A4%E6%96%AD"><span class="toc-number">19.</span> <span class="toc-text">对象类型判断</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%95%B0%E7%BB%84-1"><span class="toc-number">19.1.</span> <span class="toc-text">数组</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#js-%E5%8D%95%E7%BA%BF%E7%A8%8B%EF%BC%8C%E5%A6%82%E4%BD%95%E5%BC%82%E6%AD%A5"><span class="toc-number">20.</span> <span class="toc-text">js 单线程,如何异步</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E7%A7%BB%E5%8A%A8%E7%AB%AF%E6%9C%80%E5%B0%8F%E8%A7%A6%E6%8E%A7%E5%8C%BA%E5%9F%9F"><span class="toc-number">21.</span> <span class="toc-text">移动端最小触控区域</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#js-%E7%B2%BE%E5%BA%A6%E9%97%AE%E9%A2%98"><span class="toc-number">22.</span> <span class="toc-text">js 精度问题</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%86%BB%E7%BB%93-Object-freeze"><span class="toc-number">23.</span> <span class="toc-text">冻结 Object. freeze()</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Reflect"><span class="toc-number">24.</span> <span class="toc-text">Reflect</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#Reflect-get-target-propertyKey-value-receiver"><span class="toc-number">24.1.</span> <span class="toc-text">Reflect.get(target, propertyKey, value[receiver])</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Reflect-set-target-propertyKey-value-receiver"><span class="toc-number">24.2.</span> <span class="toc-text">Reflect.set(target, propertyKey, value[receiver])</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Reflect-has-target-propertyKey"><span class="toc-number">24.3.</span> <span class="toc-text">Reflect.has(target, propertyKey)</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#if-else-%E4%BC%98%E5%8C%96"><span class="toc-number">25.</span> <span class="toc-text">if else 优化</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%A1%A8%E9%A9%B1%E5%8A%A8%E7%BC%96%E7%A8%8B"><span class="toc-number">25.1.</span> <span class="toc-text">表驱动编程</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%9F%AD%E8%B7%AF%E8%BF%90%E7%AE%97"><span class="toc-number">25.2.</span> <span class="toc-text">短路运算</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8%E6%9C%89%E6%84%8F%E4%B9%89%E4%B8%94%E6%98%93%E8%AF%BB%E7%9A%84%E5%8F%98%E9%87%8F%E5%90%8D"><span class="toc-number">26.</span> <span class="toc-text">使用有意义且易读的变量名</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8%E6%9C%89%E6%84%8F%E4%B9%89%E7%9A%84%E5%8F%98%E9%87%8F%E4%BB%A3%E6%9B%BF%E6%95%B0%E7%BB%84%E4%B8%8B%E6%A0%87"><span class="toc-number">27.</span> <span class="toc-text">使用有意义的变量代替数组下标</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%8F%98%E9%87%8F%E5%90%8D%E8%A6%81%E7%AE%80%E6%B4%81"><span class="toc-number">28.</span> <span class="toc-text">变量名要简洁</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%B6%88%E9%99%A4%E9%AD%94%E6%9C%AF%E5%AD%97%E7%AC%A6%E4%B8%B2"><span class="toc-number">29.</span> <span class="toc-text">消除魔术字符串</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8%E9%BB%98%E8%AE%A4%E5%8F%82%E6%95%B0%E6%9B%BF%E4%BB%A3%E7%9F%AD%E8%B7%AF%E8%BF%90%E7%AE%97%E7%AC%A6"><span class="toc-number">30.</span> <span class="toc-text">使用默认参数替代短路运算符</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0"><span class="toc-number">31.</span> <span class="toc-text">一个函数</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E5%8F%82%E6%95%B0%E4%B8%8D%E5%A4%9A%E4%BA%8E-2-%E4%B8%AA%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%9C%89%E5%BE%88%E5%A4%9A%E5%8F%82%E6%95%B0%E5%B0%B1%E5%88%A9%E7%94%A8-object-%E4%BC%A0%E9%80%92%EF%BC%8C%E5%B9%B6%E4%BD%BF%E7%94%A8%E8%A7%A3%E6%9E%84"><span class="toc-number">32.</span> <span class="toc-text">函数参数不多于 2 个,如果有很多参数就利用 object 传递,并使用解构</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E5%90%8D%E5%BA%94%E8%AF%A5%E7%9B%B4%E6%8E%A5%E5%8F%8D%E6%98%A0%E5%87%BD%E6%95%B0%E7%9A%84%E4%BD%9C%E7%94%A8"><span class="toc-number">33.</span> <span class="toc-text">函数名应该直接反映函数的作用</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%B0%BD%E9%87%8F%E4%BD%BF%E7%94%A8%E7%BA%AF%E5%87%BD%E6%95%B0"><span class="toc-number">34.</span> <span class="toc-text">尽量使用纯函数</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E4%B8%8D%E8%A6%81%E8%BF%87%E5%BA%A6%E4%BC%98%E5%8C%96"><span class="toc-number">35.</span> <span class="toc-text">不要过度优化</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%85%B3%E4%BA%8E%E6%A8%A1%E5%9D%97%E5%8C%96"><span class="toc-number">36.</span> <span class="toc-text">关于模块化</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%97%A0%E6%A8%A1%E5%9D%97%E5%8C%96"><span class="toc-number">36.1.</span> <span class="toc-text">无模块化</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#CommonJS-%E8%A7%84%E8%8C%83-%E5%90%8C%E6%AD%A5"><span class="toc-number">36.2.</span> <span class="toc-text">CommonJS 规范(同步)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#AMD-%E8%A7%84%E8%8C%83-RequireJS"><span class="toc-number">36.3.</span> <span class="toc-text">AMD 规范(RequireJS)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#CMD-%E8%A7%84%E8%8C%83-SeaJS"><span class="toc-number">36.4.</span> <span class="toc-text">CMD 规范(SeaJS)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#ES6-import-x2F-export"><span class="toc-number">36.5.</span> <span class="toc-text">ES6 import&#x2F;export</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#AMD%E6%A8%A1%E5%9D%97%E5%8C%96%E5%AE%9E%E7%8E%B0"><span class="toc-number">37.</span> <span class="toc-text">AMD模块化实现</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#define-%E5%87%BD%E6%95%B0"><span class="toc-number">37.1.</span> <span class="toc-text">define 函数</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#deps-%E4%BE%9D%E8%B5%96-%E5%AF%BC%E5%85%A5"><span class="toc-number">37.2.</span> <span class="toc-text">deps 依赖(导入)</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%80%81%E7%94%9F%E5%B8%B8%E8%B0%88%E7%9A%84%E6%8C%87%E9%92%88"><span class="toc-number">37.3.</span> <span class="toc-text">老生常谈的指针</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E7%BC%98%E8%B5%B7-Object-defineProperty"><span class="toc-number">38.</span> <span class="toc-text">缘起 Object.defineProperty()</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E4%B8%8A%E5%B8%9D%E7%9A%84%E9%92%A5%E5%8C%99-get-amp-set"><span class="toc-number">39.</span> <span class="toc-text">上帝的钥匙 get &amp; set</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%B0%81%E8%A3%85-defineReactive-obj-prop-val"><span class="toc-number">40.</span> <span class="toc-text">封装 defineReactive(obj, prop, val)</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E9%80%92%E5%BD%92%E4%BE%A6%E6%B5%8B"><span class="toc-number">41.</span> <span class="toc-text">递归侦测</span></a></li></ol>
</div>
</div>
</cosy-drag-box>
</div>
</div>
<script>
window.page = {
use: ''
}
window.katex = {
enable: "",
jsCdn: "//cdn.jsdelivr.net/npm/katex@0.13.18/dist/katex.min.js",
cssCdn: "//cdn.jsdelivr.net/npm/katex@0.13.18/dist/katex.min.css"
}
window.mermaid = {
enable: "",
theme: "",
cdn: "//cdn.jsdelivr.net/npm/mermaid@10.4.0/dist/mermaid.min.js",
}
window.valine = {
enable: "",
appId: 'TisMit6uhflounFqAN3ZGjgq-MdYXbMMI',
appKey: 'CdjirjYdz07U5i62ElsJvXUh',
avatar: 'monsterid',
cdn: '//unpkg.com/valine@latest/dist/Valine.min.js',
serverURLs: '//tismit6u.api.lncldglobal.com'
};
</script>
<script src="/js/0af3d6bb.js"></script>
</main>
</body>
<script>
window.theme = {
color: 'hsl(238,50%,56%)'
}
</script>
<script src="/js/9c8197f9.js"></script>
</html>