当前位置:首页 > 科技  > 软件

面试官:你能实现一个 JavaScript 模板引擎吗?

来源: 责编: 时间:2024-05-29 08:57:07 291观看
导读Hello,大家好,我是 Sunday。这个问题具体是这样的:请为字符串增加一个 render 方法,可以实现如下最终的打印。const template = '我是 ${name}, 年龄 ${age} 岁'const employee = { name: 'Sunday', age: 18}const rend

Hello,大家好,我是 Sunday。0q428资讯网——每日最新资讯28at.com

这个问题具体是这样的:请为字符串增加一个 render 方法,可以实现如下最终的打印。0q428资讯网——每日最新资讯28at.com

const template = '我是 ${name}, 年龄 ${age} 岁'const employee = {  name: 'Sunday',  age: 18}const renderStr = template.render(employee)// 输出成字符串console.log(renderStr) // '我是 Sunday, 年龄 18 岁'

乍一看,这不就是 模板引擎 吗?合着这是让我手写一个 `` 的简易版出来啊。0q428资讯网——每日最新资讯28at.com

不过还好,既然是简易版那就并不复杂。一共有三种方式,咱们来看看吧!0q428资讯网——每日最新资讯28at.com

01:利用正则表达式

使用正则表达式应该是大多数的同学第一时间想到的方案了。0q428资讯网——每日最新资讯28at.com

只需要通过正则替换 ${name} 和 ${age} 就可以直接实现对应的功能。0q428资讯网——每日最新资讯28at.com

String.prototype.render = function (obj) {  const template = this  const variableRegex = //$/{([^${}]+)/}/g  template.replace(variableRegex, ($0, variable) => {     // 打印对应的属性    console.log(variable)  })}const template = '我是 ${name}, 年龄 ${age} 岁'template.render()

通过以上代码我们可以直接拿到 ${name} 之中的属性,所以接下来咱们就只需要完成替换即可。0q428资讯网——每日最新资讯28at.com

// 为 String 对象的原型添加一个名为 render 的方法String.prototype.render = function (obj) {  // 保存调用该方法的字符串实例  const template = this;  // 定义一个正则表达式,用于匹配 ${variableName} 格式的变量  const variableRegex = //$/{([^${}]+)/}/g;  // 定义一个函数,用于根据传入的对象获取变量的值  const getVariableValue = (variable) => {    // 将变量名按照 '.' 分隔成数组,例如 'user.name' 会分隔成 ['user', 'name']    variable = variable.split('.');    // 初始化 variableValue,使其指向传入的对象 obj    let variableValue = obj;    // 遍历分隔后的变量名数组,逐层获取嵌套属性的值    while (variable.length) {      // 取出数组的第一个元素,并获取对应的属性值      variableValue = variableValue[variable.shift()];    }    // 返回最终获取到的变量值    return variableValue;  };  // 使用 replace 方法替换模板字符串中的变量  // $0 是匹配到的整个字符串,例如 ${name}  // variable 是捕获组中的变量名,例如 name  const renderStr = template.replace(variableRegex, ($0, variable) => {    // 获取变量值并替换模板中的变量    return getVariableValue(variable);  });  // 返回替换后的字符串  return renderStr;};

02:使用 eval

eval() 函数会将传入的字符串当做 JavaScript 代码进行执行。0q428资讯网——每日最新资讯28at.com

比如:0q428资讯网——每日最新资讯28at.com

const employee = {  name: 'Sunday',  age: 18}const { name } = employeeconsole.log(name) // Sunday

这样的代码使用 eval 方法可以这么写:0q428资讯网——每日最新资讯28at.com

const employee = {  name: 'Sunday',  age: 18}// 注意:必须是 vareval('var { name } = employee')console.log(name) // Sunday

这样的好处在于 可以根据 obj 的 key 动态的生成新的变量。0q428资讯网——每日最新资讯28at.com

因此,就可以得到如下代码:0q428资讯网——每日最新资讯28at.com

// 为 String 对象的原型添加一个名为 render 的方法String.prototype.render = function (obj) {  // 保存调用该方法的字符串实例  const template = this;  // 使用 eval 动态解构 obj 对象,将其属性名作为变量名,并赋值给这些变量  // 例如,obj = { name: 'Sunday', age: 18}  // 生成的代码类似于:var { name, age, job } = obj;  eval(`var {${Object.keys(obj).join(',')}} = obj`);  // 使用模板字符串替换变量,并生成最终的字符串  // 这里的 eval 用于解析和执行模板字符串,其中包含 obj 对象的属性值  // 例如,template = '我是 ${name}, 年龄 ${age} 岁'  // 生成的代码类似于:`我是 ${name}, 年龄 ${age} 岁`  const renderStr = eval('`' + template + '`');  // 返回替换后的字符串  return renderStr;}

03:with 关键字

with 语句扩展一个语句的作用域链0q428资讯网——每日最新资讯28at.com

with 关键字属于被弃用的语法(但是 Vue3 的源码中依然使用到了 with),但是在这里依然可以实现对应的功能。0q428资讯网——每日最新资讯28at.com

图片图片0q428资讯网——每日最新资讯28at.com

我们可以通过以下示例来演示 with 的作用:0q428资讯网——每日最新资讯28at.com

const employee = {  name: 'Sunday',  age: 18}with (employee) {  console.log(name, age)  // Sunday 18}

基于这个特性,使用 with 实现这个功能就非常简单了。0q428资讯网——每日最新资讯28at.com

String.prototype.render = function (obj) {  with(obj) {     // this 实例。即:我是 ${name}, 年龄 ${age} 岁     // 两边加上 ` ` 即可利用 ES6 的模板运算符实现此功能    return eval('`' + this + '`')  }}

本文链接:http://www.28at.com/showinfo-26-91363-0.html面试官:你能实现一个 JavaScript 模板引擎吗?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 记一次 .NET某工控WPF程序被人恶搞的卡死分析

下一篇: Python 对象的行为是怎么区分的?

标签:
  • 热门焦点
  • 线程通讯的三种方法!通俗易懂

    线程通信是指多个线程之间通过某种机制进行协调和交互,例如,线程等待和通知机制就是线程通讯的主要手段之一。 在 Java 中,线程等待和通知的实现手段有以下几种方式:Object 类下
  • 2023 年的 Node.js 生态系统

    随着技术的不断演进和创新,Node.js 在 2023 年达到了一个新的高度。Node.js 拥有一个庞大的生态系统,可以帮助开发人员更快地实现复杂的应用。本文就来看看 Node.js 最新的生
  • CSS单标签实现转转logo

    转转品牌升级后更新了全新的Logo,今天我们用纯CSS来实现转转的新Logo,为了有一定的挑战性,这里我们只使用一个标签实现,将最大化的使用CSS能力完成Logo的绘制与动画效果。新logo
  • 从 Pulsar Client 的原理到它的监控面板

    背景前段时间业务团队偶尔会碰到一些 Pulsar 使用的问题,比如消息阻塞不消费了、生产者消息发送缓慢等各种问题。虽然我们有个监控页面可以根据 topic 维度查看他的发送状态,
  • 零售大模型“干中学”,攀爬数字化珠峰

    文/侯煜编辑/cc来源/华尔街科技眼对于绝大多数登山爱好者而言,攀爬珠穆朗玛峰可谓终极目标。攀登珠峰的商业路线有两条,一是尼泊尔境内的南坡路线,一是中国境内的北坡路线。相
  • OPPO、vivo、小米等国内厂商Q2在印度智能手机市场份额依旧高达55%

    7月20日消息,据外媒报道,研究机构的报告显示,在全球智能手机出货量同比仍在下滑的大背景下,印度这一有潜力的市场也未能幸免,出货量同比也有下滑,多家厂
  • 超级标准版旗舰!iQOO 11S全球首发iQOO超算独显芯片

    上半年已接近尾声,截至目前各大品牌旗下的顶级旗舰都已悉数亮相,而下半年即将推出的顶级旗舰已经成为了数码圈爆料的主流,其中就包括全新的iQOO 11S系
  • 首发天玑9200+ iQOO Neo8系列发布首销售价2299元起

    2023年5月23日晚,iQOO Neo8系列正式发布。其中,Neo系列首款Pro之作——iQOO Neo8 Pro强悍登场,限时售价3099元起;价位段最强性能手机iQOO Neo8同期上市
  • 联想YOGA 16s 2022笔记本将要推出,屏幕支持触控功能

    联想此前宣布,将于11月2日19:30召开联想秋季轻薄新品发布会,推出联想 YOGA 16s 2022 笔记本等新品。官方称,YOGA 16s 2022 笔记本将搭载 16 英寸屏幕,并且是一
Top