• 字符串-模板编译


    模板编译

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

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

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

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

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

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

    1、构建模板生成函数

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

    const compile = function (template) {
                // 模板字符串
                let result = ''
    
                return new Function('obj', result)
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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 = "

    Hello, I'm {{user.name}}! {{user.age}} years old!

    "
    // 调用compile传入template const render = compile(template) console.log(render)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    输出的结果:

     anonymous(obj) {
         return "

    Hello, I'm obj.user.name! obj.user.age years old!

    "
    }
    • 1
    • 2
    • 3

    这里例子就是将传入的字符串通过正则匹配,并且将它替换成表达式的形式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);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

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

    const data = {
              user: {
                 name: 'hayes',
                 age: 18
                 }
             }
    const template = "

    Hello, I'm {{user.name}}! {{user.age}} years old!

    "
    const render = compile(template) const result = render(data) console.log(result)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    传入的值经过了处理,在template.replace下面的return这里实际上将字符串变成了这种形式
    在这里插入图片描述
    只需要将返回的结果渲染到页面即可,最终的结果:
    在这里插入图片描述

    完整版:

    const compile = function (template) {
           // 模板字符串
           let result = template.replace(/{{(.+?)}}/g, (match, key) => {
                // 前后加上引号
                return `" + obj.${key} + "`
                // 此处就变成了 "

    Hello, I'm " + obj.user.name + "! " + obj.user.age + " years old!

    "
    }); result = `return "${result}"`; return new Function('obj', result); } const template = "

    Hello, I'm {{user.name}}! {{user.age}} years old!

    "
    const render = compile(template) const data = { user: { name: 'hayes', age: 18 } } const result = render(data) console.log(result)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    在这里插入图片描述


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

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

  • 相关阅读:
    流媒体服务器ZLMediaKit与FFmpeg
    华为设备配置攻击溯源命令
    Nodejs 第四十一章(项目架构MVC,IoC,DI)
    Spring JDBC
    Linux查询文件和字符串命令
    计算机网络工程师多选题系列——计算机网络
    数据结构 - 图
    C++基础之类二(六个成员函数、构造及析构)待完善
    PPPoE lcp和ncp协商
    Kafka KRaft模式探索
  • 原文地址:https://blog.csdn.net/qq_44793507/article/details/128193967