代码细节缓存代理函数export function cached<F: Function> (fn: F): F { const cache = Object.create(null) return (function cachedFn (str: string) { const hit = cache[str] return hit || (cache[str] = fn(str)) }: any)} vue源码里面大量使用的一个缓存代理函数。缓存参数执行结果,如果下次是同一个参数来调用函数,将返回上次产生的结果,而不是再次调用函数。获取元素的outHTML/** * Get outerHTML of elements, taking care * of SVG elements in IE as well. */function getOuterHTML (el: Element): string { if (el.outerHTML) { return el.outerHTML } else { const container = document.createElement(‘div’) container.appendChild(el.cloneNode(true)) return container.innerHTML }} 考虑ie下面的svg无法获取outHTML(undefined),转为获取innerHTML过滤器模板解析函数const validDivisionCharRE = /[\w).+-_$]]/export function parseFilters (exp: string): string { let inSingle = false let inDouble = false let inTemplateString = false let inRegex = false let curly = 0 let square = 0 let paren = 0 let lastFilterIndex = 0 let c, prev, i, expression, filters for (i = 0; i < exp.length; i++) { prev = c c = exp.charCodeAt(i) // 0x5C => \ if (inSingle) { if (c === 0x27 && prev !== 0x5C) inSingle = false } else if (inDouble) { if (c === 0x22 && prev !== 0x5C) inDouble = false } else if (inTemplateString) { if (c === 0x60 && prev !== 0x5C) inTemplateString = false } else if (inRegex) { if (c === 0x2f && prev !== 0x5C) inRegex = false } else if ( c === 0x7C && // | exp.charCodeAt(i + 1) !== 0x7C && exp.charCodeAt(i - 1) !== 0x7C && !curly && !square && !paren ) { if (expression === undefined) { // first filter, end of expression lastFilterIndex = i + 1 expression = exp.slice(0, i).trim() } else { pushFilter() } } else { switch (c) { case 0x22: inDouble = true; break // " case 0x27: inSingle = true; break // ’ case 0x60: inTemplateString = true; break // case 0x28: paren++; break // ( case 0x29: paren--; break // ) case 0x5B: square++; break // [ case 0x5D: square--; break // ] case 0x7B: curly++; break // { case 0x7D: curly--; break // } } if (c === 0x2f) { // / let j = i - 1 let p // find first non-whitespace prev char for (; j &gt;= 0; j--) { p = exp.charAt(j) if (p !== ' ') break } if (!p || !validDivisionCharRE.test(p)) { inRegex = true } } } } if (expression === undefined) { expression = exp.slice(0, i).trim() } else if (lastFilterIndex !== 0) { pushFilter() } function pushFilter () { (filters || (filters = [])).push(exp.slice(lastFilterIndex, i).trim()) lastFilterIndex = i + 1 } if (filters) { for (i = 0; i &lt; filters.length; i++) { expression = wrapFilter(expression, filters[i]) } } return expression}function wrapFilter (exp: string, filter: string): string { const i = filter.indexOf('(') if (i &lt; 0) { // _f: resolveFilter return_f("${filter}")(${exp}) } else { const name = filter.slice(0, i) const args = filter.slice(i + 1) return_f("${name}")(${exp}${args !== ‘)’ ? ‘,’ + args : args} }} vue有一个api叫做filters,我们可以用它来格式化我们的变量,用法类似:&lt;!-- 在双花括号中 --&gt;{{ message | capitalize }}&lt;!-- 在v-bind` 中 –><div v-bind:id=“rawId | formatId”></div> 由“管道”符号分割,表达式为管道符最前面的一项,后面跟随若干过滤器函数。{{input | filter1 | filter2 }} 解析为:f(“filter2”)(f(“filter1”)(input))如何分割过滤器呢,从函数中可以看到,在任何封闭符号的表达式后面,如果出现管道符’|‘则将之前的字符串视为一个过滤器或者表达式。封闭符号则包括引号、括号、模板符号以及正则表达式,除正则表达式之外的符号判断都很简单,直接匹配响应符号的Unicode就行。但是正则表达式需要特殊处理:当匹配到第一个非封闭的’/‘符号时,要校验它之前的第一个非空字符。我们知道,正则前面是不能有任何非空符号的。采用正则表达式来匹配这一规则:/[\w).+-$]]/ // 匹配任意[A-Za-z0-9] . + - _ $ ]