自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

三種實(shí)現(xiàn) JavaScript 模板引擎的方法

開(kāi)發(fā) 前端
小伙伴們,相信即使你是經(jīng)驗(yàn)豐富的開(kāi)發(fā)者,也未必能很快的解決這道面試題。如果您想質(zhì)疑這一說(shuō)法,請(qǐng)繼續(xù)閱讀下去。

小伙伴們,相信即使你是經(jīng)驗(yàn)豐富的開(kāi)發(fā)者,也未必能很快的解決這道面試題。如果您想質(zhì)疑這一說(shuō)法,請(qǐng)繼續(xù)閱讀下去。

最近,我的好朋友南希遇到了一個(gè)讓她發(fā)瘋的問(wèn)題,面試官要求她現(xiàn)場(chǎng)實(shí)現(xiàn)一個(gè)JavaScript模板引擎。

很傷心,因?yàn)槲业呐笥阎皇窃谡夜ぷ?,但面試官讓她造一架飛機(jī)。

問(wèn)題如下:

請(qǐng)向 String 對(duì)象添加一個(gè) render(obj) 方法,它的作用是將字符串中的特定字符替換為obj的相應(yīng)屬性。

const template = 'My name is ${name}, age ${age}, I am a ${job.name}'
const employee = {
name: 'fatfish',
age: 100,
job: {
name: 'front end development'
}
}
const renderStr = template.render(employee)
// What is the output string?
console.log(renderStr) // 'My name is fatfish, age 100, I am a front end development'

什么是模板引擎?

你一定用過(guò)nunjucks之類的模板引擎,題型和它的功能很像,請(qǐng)跟著我一起舉個(gè)例子。

nunjucks.configure({ autoescape: true })
const template = 'My name is `name`, age `age`, I am a `job`.`name`'
const employee = {
name: 'fatfish',
age: 100,
job: {
name: 'front end development'
}
}
const renderStr = nunjucks.renderString(template, employee)
console.log(renderStr) // My name is fatfish, age 100, I am a front end development

我可憐的朋友被要求實(shí)現(xiàn)這樣的東西,它只是將 ${name} 替換為 `name` 而幾乎沒(méi)有別的。

解決方案 1:正則表達(dá)式

看到這個(gè)面試題,我的第一反應(yīng)是用正則表達(dá)式來(lái)解決。只要我們能提取出字符串中的具體字符(name、age、job.name),問(wèn)題就迎刃而解了。

第 1 步:提取變量

String.prototype.render = function (obj) {
const template = this
const variableRegex = /\$\{([^${}]+)\}/g
template.replace(variableRegex, ($0, variable) => {
console.log(variable)
})
}
const template = 'My name is ${name}, age ${age}, I am a ${job.name}'
template.render()

圖片

太好了,我們得到了 name、age、job.name 變量。下面我們來(lái)看看這個(gè)正則表達(dá)式是什么意思,可以點(diǎn)這個(gè)鏈接:https://jex.im/regulex/#!flags=&re=%5C%24%5C%7B(%5B%5E%24%7B%7D%5D%2B)%5C%7D進(jìn)行查看。

const variableRegex = /\$\{([^${}]+)\}/g

我們要關(guān)注 ([^${}]+),這意味著至少有一個(gè)除 $、{、} 之外的字符。

第二步:獲取obj的具體值

當(dāng)我們得到name, age, job.name,如何關(guān)聯(lián)到employee?


String.prototype.render = function (obj) {
const template = this
const variableRegex = /\$\{([^${}]+)\}/g
const getVariableValue = (variable) => {
// [ 'name' ]、[ 'age' ]、[ 'job', 'name' ]
variable = variable.split('.')
let variableValue = obj
// For example, if we want to get the value of job.name, we will go through the following steps
// Initialization: variableValue = { name: 'fatfish', age: 100, job: { name: "front end development" } }
// first loop: variableValue = { name: "front end development" }
// Second loop: variableValue = 'front end development'
// Third loop: finished, return 'front end development'
while (variable.length) {
variableValue = variableValue[ variable.shift() ]
}
return variableValue
}
const renderStr = template.replace(variableRegex, ($0, variable) => {
return getVariableValue(variable)
})
return renderStr
}

const template = 'My name is ${name}, age ${age}, I am a ${job.name}'
const employee = {
name: 'fatfish',
age: 100,
job: {
name: 'front end development'
}
}
const renderStr = template.render(employee)

console.log(renderStr)

我們通過(guò)正則表達(dá)式實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的模板引擎,請(qǐng)小伙伴們?yōu)樽约捍驓狻?/p>

解決方案 2:eval

朋友們,讓我們回顧一下es6中模板字符串的基本用法。

const name = 'fatfish'
const age = 100
const job = {
name: 'front end development'
}
const renderString = `My name is ${name}, age ${age}, I am a ${job.name}`

console.log(renderString)

模板字符串非常有用,它們?cè)试S我們?cè)谧址星度氡磉_(dá)式。

圖片

讓我們?cè)俅螌W(xué)習(xí)如何使用 eval。

const employee = {
name: 'fatfish',
age: 100,
job: {
name: 'front end development'
}
}
eval('var { name, age, job } = employee')

console.log(name, age, job)

很神奇,就好像我們聲明了三個(gè)變量name、age、job,我們可以隨意打印出它們的值。

有了這兩個(gè)知識(shí)點(diǎn),我們的第二個(gè)方案就出來(lái)了。

String.prototype.render = function (obj) {
const template = this
// var { name, age, job } = obj
eval(`var {${Object.keys(obj).join(',')}} = obj`)
// `My name is ${name}, age ${age}, I am a ${job.name}`
const renderStr = eval('`' + template + '`')
return renderStr
}
const template = 'My name is ${name}, age ${age}, I am a ${job.name}'
const employee = {
name: 'fatfish',
age: 100,
job: {
name: 'front end development'
}
}

const renderStr = template.render(employee)

圖片

給自己鼓掌,因?yàn)槟阋呀?jīng)用兩種方式實(shí)現(xiàn)了一個(gè)精簡(jiǎn)版模板引擎。

解決方案3:with

雖然我們很少用到with關(guān)鍵字,但是可以用來(lái)解決這個(gè)問(wèn)題。

這段代碼的輸出是什么?

const employee = {
name: 'fatfish',
age: 100,
job: {
name: 'front end development'
}
}
with (employee) {
console.log(name, age, job)
}

圖片

這與上面的代碼幾乎具有相同的效果,但更加簡(jiǎn)潔易懂。

// var { name, age, job } = obj
eval(`var {${Object.keys(obj).join(',')}} = obj`)

好吧,我想你已經(jīng)猜到了答案。

String.prototype.render = function (obj) {
with(obj) {
return eval('`' + this + '`')
}
}
const template = 'My name is ${name}, age ${age}, I am a ${job.name}'
const employee = {
name: 'fatfish',
age: 100,
job: {
name: 'front end development'
}
}
const renderStr = template.render(employee)

console.log(renderStr)

最后總結(jié)

以上就是我今天跟你分享的3種JavaScript模板引擎的實(shí)現(xiàn)方法,希望對(duì)你有幫助,如果你覺(jué)得有用的話,請(qǐng)點(diǎn)贊我,關(guān)注我,并將它分享給你周圍的朋友。

責(zé)任編輯:華軒 來(lái)源: web前端開(kāi)發(fā)
相關(guān)推薦

2020-09-08 12:53:47

C++數(shù)據(jù)線程

2022-01-04 16:50:47

JavaScript圖片網(wǎng)站

2010-09-30 15:37:29

ScrollBarJavascrip

2017-12-29 08:26:28

存儲(chǔ)引擎MySQL

2021-07-13 12:31:27

IT組織改進(jìn)首席技術(shù)官

2013-01-04 15:47:54

Android開(kāi)發(fā)平鋪UI設(shè)計(jì)

2015-05-07 15:19:47

IaaSPaaSAzure

2019-08-30 17:24:41

microservic微服務(wù)

2009-07-08 12:56:32

編寫Servlet

2015-12-11 09:24:38

加密數(shù)據(jù)Linux

2016-09-12 14:07:14

Android 定時(shí)器

2014-12-31 17:42:47

LBSAndroid地圖

2021-06-24 08:52:19

單點(diǎn)登錄代碼前端

2021-11-05 21:33:28

Redis數(shù)據(jù)高并發(fā)

2024-11-06 09:28:52

架構(gòu)客戶端靜態(tài)

2010-08-26 16:19:41

DIV圓角

2010-09-06 10:04:31

CSS樣式表

2009-05-07 15:02:42

OracleJoin查詢

2009-12-09 09:48:38

solaris靜態(tài)路由

2011-06-10 10:43:12

Ubuntu應(yīng)用安裝
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)