字符串-模板编译

简介: 字符串-模板编译

模板编译


编译就是一种格式转换成另一种格式的过程,这里主要讨论一下模板编译。模板字符串对比普通的字符串有很多的不同,模板字符串可以嵌套,并且模板字符串可以在内部使用${xxx}进行表达式运算以及函数调用,这些其实都是模板编译的结果。

普通的字符串编译也就是字符拼接,如果在字符串内使用参数或者表达式,那么就需要用+号连接,例如:

let market = document.getElementById('market')
let num = 5   // 数量
let money = 4  // 金额
market.innerHTML = "总共卖出" + num + "杯柠檬水,总金额:" + num * money + "元"

如果用模板字符串来表达的会更加简洁,而且不需要字符串拼接,并且在内部可以直接使用表达式,例如:

market.innerHTML = `总共卖出${num}杯柠檬水,总金额:${num * money}元`

普通字符串跟模板字符串得出来的结果是一样的,可以这么说,其实就是模板字符串经过了编译处理,使字符串操作更简洁,原本需要繁琐的字符串拼接,在这里直接用模板字符串就可以解决,模板字符串是怎么样编译的呢,这里就来拆解一下模板字符串的编译过程。

1、构建模板生成函数

这里就是模板字符串编译的框架,构建一个compile 函数,通过new Function 方式返回一个新函数,新函数接收一个obj对象,通过return返回最终结果。

const compile = function (template) {
            // 模板字符串
            let result = ''
            return new Function('obj', result)
        }

2、正则替换

正则不仅可以做数据校验,还可以对传入的内容进行判断,对符合条件的内容做操作,在这里,正则起了一个替换的作用。

// compile 函数
 const compile = function (template) {
       // 模板字符串
       let result = template.replace(/{{(.+?)}}/g, (match, key) => {
          return `obj.${key}`
       });
          result = `return "${result}"`;
          return new Function('obj', result);
  }
// 字符串模板
const template = "<p>Hello, I'm {{user.name}}! {{user.age}} years old!</p>"
// 调用compile传入template 
const render = compile(template)
console.log(render)

输出的结果:

anonymous(obj) {
     return "<p>Hello, I'm obj.user.name! obj.user.age years old!</p>"
    }

这里例子就是将传入的字符串通过正则匹配,并且将它替换成表达式的形式obj.user.nameobj.user.age,虽然有了表达式,但它归根结底还是一个字符串,无法编译,我们需要把obj.user.nameobj.user.age变成动态的,并且能够编译。

3、修改正则

只需要修改一下正则即可,让字符串变成最上面提到过的,字符串拼接的形式即可。

const compile = function (template) {
   // 模板字符串
   let result = template.replace(/{{(.+?)}}/g, (match, key) => {
   // 前后加上引号
   return `" + obj.${key} + "`
    });
      result = `return "${result}"`;
      return new Function('obj', result);
    }

template.replace这里,将符合条件的位置替换,变成字符串拼接的形式。

const data = {
          user: {
             name: 'hayes',
             age: 18
             }
         }
const template = "<p>Hello, I'm {{user.name}}! {{user.age}} years old!</p>"
const render = compile(template)
const result = render(data)
console.log(result)

传入的值经过了处理,在template.replace下面的return这里实际上将字符串变成了这种形式

只需要将返回的结果渲染到页面即可,最终的结果:

完整版:

const compile = function (template) {
       // 模板字符串
       let result = template.replace(/{{(.+?)}}/g, (match, key) => {
            // 前后加上引号
            return `" + obj.${key} + "`
            // 此处就变成了 "<p>Hello, I'm " + obj.user.name + "! " + obj.user.age + " years old!</p>"
            });
            result = `return "${result}"`;
            return new Function('obj', result);
        }
const template = "<p>Hello, I'm {{user.name}}! {{user.age}} years old!</p>"
const render = compile(template)
const data = {
         user: {
             name: 'hayes',
             age: 18
           }
        }
const result = render(data)
console.log(result)


案例源码:https://gitee.com/wang_fan_w/es6-science-institute

如果觉得这篇文章对你有帮助,欢迎点亮一下star哟

目录
相关文章
|
3月前
模板字符串
模板字符串
18 1
|
3月前
|
JSON JavaScript 前端开发
设置WebStorm像VSCode一样每行代码结尾自动格式化加入“;”分号(JavaScript、TypeScript格式化)
设置WebStorm像VSCode一样每行代码结尾自动格式化加入“;”分号(JavaScript、TypeScript格式化)
|
19天前
|
IDE API 开发工具
|
4天前
|
JavaScript 前端开发
什么是模板字符串?
什么是模板字符串?
10 0
|
9月前
ES6系列笔记-字符串方法和字符串模板
ES6系列笔记-字符串方法和字符串模板
29 1
|
10月前
|
C语言 C++ 容器
【C++】模板进阶:非类型模板参数&模板的特化&模板分离编译(上)
【C++】模板进阶:非类型模板参数&模板的特化&模板分离编译(上)
|
10月前
|
编译器 C语言 C++
【C++】模板进阶:非类型模板参数&模板的特化&模板分离编译(下)
【C++】模板进阶:非类型模板参数&模板的特化&模板分离编译(下)
【STM32】【vscode编译】 不允许使用与号(&)。& 运算符是为将来使用而保留的;请用双引号将与号引起来(\“&\“),以将其作为字符串的一部分传递
【STM32】【vscode编译】 不允许使用与号(&)。& 运算符是为将来使用而保留的;请用双引号将与号引起来(\“&\“),以将其作为字符串的一部分传递
371 0
|
JavaScript 前端开发
一分钟让你学会模板字符串
一分钟让你学会模板字符串
108 0