阅读 135

前端必刷手写题系列 [10]

这是我参与更文挑战的第 12 天,活动详情查看 更文挑战

这个系列也没啥花头,就是来整平时面试的一些手写函数,考这些简单实现的好处是能看出基本编码水平,且占用时间不长,更全面地看出你的代码实力如何。一般不会出有很多边界条件的问题,那样面试时间不够用,考察不全面。

平时被考到的 api 如果不知道或不清楚,直接问面试官就行, api 怎么用这些 Google 下谁都能马上了解的知识也看不出水平。关键是在实现过程,和你的编码状态习惯思路清晰程度等。

注意是简单实现,不是完整实现,重要的是概念清晰实现思路清晰,建议先解释清除概念 => 写用例 => 写伪代码 => 再实现具体功能,再优化,一步步来。

19. 模板解析(模板字符串)

是什么

关键点有这两个

1. String.prototype.replace() 这个 api 的使用

replace() 方法返回一个由替换值(replacement)替换部分或所有的模式(pattern)匹配项后的新字符串。模式可以是一个字符串或者一个正则表达式,替换值可以是一个字符串或者一个每次匹配都要调用的回调函数。如果pattern是字符串,则仅替换第一个匹配项。

语法

str.replace(regexp|substr, newSubStr|function)

参数

regexp (pattern)

  • 一个RegExp 对象或者其字面量。该正则所匹配的内容会被第二个参数的返回值替换掉。

substr (pattern)

  • 一个将被 newSubStr 替换的 字符串。其被视为一整个字符串,而不是一个正则表达式。仅第一个匹配项会被替换

newSubStr (replacement)

  • 用于替换掉第一个参数在原字符串中的匹配部分的字符串。该字符串中可以内插一些特殊的变量名。参考下面的使用字符串作为参数。

function (replacement)

  • 一个用来创建新子字符串的函数,该函数的返回值将替换掉第一个参数匹配到的结果。参考下面的指定一个函数作为参数。

返回值

  • 一个部分或全部匹配由替代模式所取代的新的字符串。

描述

  • 该方法并不改变调用它的字符串本身,而只是返回一个新的替换后的字符串

  • 在进行全局的搜索替换时,正则表达式需包含 g 标志。

2. 正则表达式

MDN

我们要了解一些基本点

  1. .可以匹配任意字符,所以:

'xx.'可以匹配'xxc'、'xxo'、'x!'

  1. 特殊符号需\转义匹配

  2. \s可以匹配一个空格(也包括Tab等空白符),所以\s+表示至少有一个空格,例如匹配' ',' '

  3. 如果直接给出字符,就是精确匹配。用\d可以匹配一个数字\w可以匹配一个字母或数字

  4. 要匹配变长的字符,在正则表达式中,

  • *表示任意个字符(包括0个)
  • +表示至少一个字符
  • ?表示0个或1个字符
  • {n}表示n个字符
  • {n,m}表示n-m个字符
  1. 最后需要特别指出的是,正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符

简单手写实现

实现

  1. 先写测试用例
let name = 'More'
let sex = 'man'
let extra = '!!!'
let data = {name, sex, extra}

// ${} 类型的模板字符串
let strWith$ = '${extra} Hello ${name}, you are a ${sex}'
console.log(render1(strWith$)(data))
// !!! Hello More, you are a man

// {{}} 类型的模板字符串
let strWithDoubleParentheses = '{{extra}} Hello {{name}}, you are a {{sex}}'
console.log(render2(strWithDoubleParentheses, data))
// !!! Hello More, you are a man
复制代码
  1. 实现主逻辑
function render1(template) {
    return function(data) {
        return template.replace(/\$\{(.*?)\}/g, (match, key) => data[key]);
    }
}

// 除了正则不同 基本没啥变化
function render2(template, data) {
  return template.replace(/\{\{(\w+)\}\}/g, (match, key) => data[key]);
}
复制代码

这里面两个正则简单解释下

  1. /\$\{(.*?)\}/g
// 后面的 g 是全局的意思,上面已经说过了
我们可以分步写
1. //g
2. /\$\{\}/g     // 就是特殊符号需`\`转义匹配
3. /\$\{(.*?)\}/g   // 匹配中间可变长变量名字符串 (.*?) (\w+) 都行
复制代码
  1. /\{\{(\w+)\}\}/g 达到的效果是一样的
`\w` 可以匹配一个字母或数字
`\w+`可以匹配至少一个字母或数字,可以匹配中间的变量名
复制代码

平时简单的正则可以稍微记录下,事半功倍,你正则可以写的不6,但至少要会读懂,知晓原理,并能找到合适工具验证你找来的可用的正则。

另外正则表达式原理我之后会在 **[核心概念系列]** 单写文章,敬请期待。

另外向大家着重推荐下另一个系列的文章,非常深入浅出,对前端进阶的同学非常有作用,墙裂推荐!!!核心概念和算法拆解系列 记得点赞哈

今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦 点击此处交个朋友 Or 搜索我的微信号infinity_9368,可以聊天说地 加我暗号 "天王盖地虎" 下一句的英文,验证消息请发给我 presious tower shock the rever monster,我看到就通过,加了之后我会尽我所能帮你,但是注意提问方式,建议先看这篇文章:提问的智慧

参考

文章分类
前端
文章标签