当前位置: 首页 > 科技观察

JavaScript模板引擎的三种实现方法

时间:2023-03-12 01:01:53 科技观察

小伙伴们,相信即使你是经验丰富的开发者,也未必能很快的解决这道面试题。如果您想质疑这一说法,请继续阅读。最近,我的好朋友南希遇到了一个让她发疯的问题。面试官要求她现场实现一个JavaScript模板引擎。伤心是因为我朋友刚好找工作,面试官却让她造飞机。题目如下:请给String对象添加一个render(obj)方法,其作用是将字符串中的特定字符替换为obj的相应属性。consttemplate='我叫${name},年龄${age},我是${job.name}'constemployee={name:'fatfish',age:100,job:{name:'前端development'}}constrenderStr=template.render(employee)//输出字符串是什么?console.log(renderStr)//'我叫胖鱼,100岁,我是前端开发'什么是模板引擎?你一定用过nunjucks这样的模板引擎。问题类型与其功能非常相似。请跟我来举个例子。修女。configure({autoescape:true})consttemplate='我叫{{name}},年龄{{age}},我是{{job.name}}'constemployee={name:'fatfish',age:100,job:{name:'frontenddevelopment'}}constrenderStr=nunjucks.renderString(template,employee)console.log(renderStr)//我叫fatfish,100岁,我是前端开发的,可怜的朋友被要求实现这样的东西,它只是用{{name}}替换${name}而几乎没有别的。方案一:正则表达式看到这个面试题,我的第一反应是用正则表达式来解决。只要我们能够提取出字符串中的具体字符(name、age、job.name),问题就迎刃而解了。第一步:提取变量String.prototype.render=function(obj){consttemplate=thisconstvariableRegex=/\$\{([^${}]+)\}/gtemplate.replace(variableRegex,($0,variable)=>{console.log(variable)})}consttemplate='Mynameis${name},age${age},Iama${job.name}'template.render()太好了ok,我们得到了name,age,job.name变量。我们来看看这个正则表达式是什么意思。你可以点击这个链接:https://jex.im/regulex/#!flags=&re=%5C%24%5C%7B(%5B%5E%24%7B%7D%5D%2B)%5C%7D查看。constvariableRegex=/\$\{([^${}]+)\}/g我们要关注的是([^${}]+),这意味着至少有一个除$,{,}之外的字符。第二步:获取obj的实体值当我们得到name,age,job.name,如何关联到employee?String.prototype.render=function(obj){consttemplate=thisconstvariableRegex=/\$\{([^${}]+)\}/gconstgetVariableValue=(variable)=>{//['name']、['age']、['job','name']variable=variable.split('.')letvariableValue=obj//比如我们要获取job.name的值,会经过以下步骤//初始化:variableValue={name:'fatfish',age:100,job:{name:"frontenddevelopment"}}//第一个循环:variableValue={name:"frontenddevelopment"}//第二个循环:variableValue='frontenddevelopment'//第三个循环:finished,return'frontenddevelopment'while(variable.length){variableValue=variableValue[variable.shift()]}returnvariableValue}constrenderStr=template.replace(variableRegex,($0,variable)=>{returngetVariableValue(variable)})returnrenderStr}const吨emplate='我叫${name},年龄${age},我是${job.name}'constemployee={name:'fatfish',age:100,job:{name:'前端开发'}}constrenderStr=template.render(employee)console.log(renderStr)我们通过正则表达式实现了一个简单的模板引擎,请自己鼓励解决方案二:eval朋友们,让我们回顾一下es6中模板字符串的基本用法。constname='fatfish'constage=100constjob={name:'前端开发'}constrenderString=`我叫${name},年龄${age},我是${job.name}`console.log(renderString)模板字符串非常有用,它们允许我们在字符串中嵌入表达式。让我们再次学习如何使用eval。constemployee={name:'fatfish',age:100,job:{name:'前端开发'}}eval('var{name,age,job}=employee')console.log(name,age,job)很神奇,就好像我们声明了三个变量name、age、job,我们可以随意打印出它们的值。有了这两个知识点,我们的第二个方案就出来了。String.prototype.render=function(obj){consttemplate=this//var{name,age,job}=objeval(`var{${Object.keys(obj).join(',')}}=obj`)//`我叫${name},年龄${age},我是${job.name}`constrenderStr=eval('`'+template+'`')returnrenderStr}consttemplate='我叫${name},年龄${age},我是${job.name}'constemployee={name:'fatfish',age:100,job:{name:'前端开发'}}constrenderStr=template.render(employee)为自己鼓掌,因为你已经用两种方式实现了一个精简的模板引擎。解决方案三:with虽然我们很少使用with关键字,但是可以用它来解决这个问题。这段代码的输出是什么?constemployee={name:'fatfish',age:100,job:{name:'frontenddevelopment'}}with(employee){console.log(name,age,job)}这与上面的代码几乎相同效果,但更简洁易懂。//var{name,age,job}=objeval(`var{${Object.keys(obj).join(',')}}=obj`)嗯,我想你猜到了答案。String.prototype.render=function(obj){with(obj){returneval('`'+this+'`')}}consttemplate='我的名字是${name},年龄${age},我我是${job.name}'constemployee={name:'fatfish',age:100,job:{name:'frontenddevelopment'}}constrenderStr=template.render(employee)console.log(renderStr)最后,以上就是今天给大家分享的3个JavaScript模板引擎的实现方法。希望对您有所帮助。如果觉得有用,请点赞,关注我,分享给你的朋友。