template模板

一个简单的字符串模板

    var template = (function() { var cache = {};return function(obj, str) {if (!typeof str === "string") {return;}var compile = cache[str]if (!cache[str]) {var template = str.replace(/<%=\s*([^%>]+)\s*%>/g, function() {var k = arguments[1]var tm =  "';" + k  + " tmp+='"console.log("tm", tm)return tm;}).replace(/\$\{\s*([^\}]+)\s*\}/g, function() {var k = arguments[1]var tm = "' +" + k+ "+'";return tm;})template = "var tmp = \"\"; with(obj){tmp ='" + template + "';}return tmp;"console.log("template", template)compile = new Function("obj", template)}return compile(obj)}})()

使用

    var str = "" +"<div> "+"<ul> "+"<%= for(var i=0;i < obj.length; i++) { %> "+"<li>${obj[i].name}</li> "+"<%= } %> "+"</ul> "+"</div> "var obj = [{name: "李飞1"},{name: "李飞2"},{name: "李飞3"},];var html = template(obj, str);//生成字符串:"<div> <ul>  <li>李飞1</li>  <li>李飞2</li>  <li>李飞3</li>  </ul> </div> "

介绍

  1. template函数有两个参数,第一个是数据,第二个是字符串模板.
  2. 字符串模板的格式要求
    1. 要执行的js代码需要写在: <%= 这里 %> . 比如: <%= var a = ""; %>
    2. 从对象里拿的数据写在: ${ 这里 } . 比如: ${obj.name}
  3. 如果obj是对象的话,可以直接从对象里拿数据.比如:

        var obj = {name: "李飞"};var str = "hello, ${name}";var html = template(obj, str);  //html 为 "hello,"李飞
  4. 如果obj是数组的话,不能直接拿,需要把数组便利才能使用.

原理分析

简单来说就是,把js代码写在固定的格式中,用String.replace()方法,获取到js代码的字符串.
然后拼成一个函数格式的字符串.再用new Function()用这个函数字符串生成一个函数,去处理
模板里的字符串并返回

知识点

  1. String.replace(参数1, 参数2)

    1. 参数1,可以是字符串也可以是正则表达式,如果是正则表示式.并且有全局匹配g的话,会替换所有的匹配项.如果此时参数2是函数,那么有多少个匹配项,函数就会执行杜少次
    2. 参数2,可以是字符串,也可以是回调函数.函数的返回值会替代匹配的字符串.而回调函数的参数是一般有四个.可以用arguments来拿;
      1. 第一个参数是正则匹配到的字符串
      2. 第二个参数是与正则表达式中子表达式相匹配的字符串.也就是正则中的括号()匹配到的字符串.也即是template函数中我们需要拼接的js字符串.
      3. 如果子表达式有2个,则这里是第二个.多个以此类推.如果子表达式没有了.这里是整个被匹配到的字符串所在的length.
      4. 完整的原始字符串;
    3. replace函数不改变源字符串.返回值是替换之后的结果
  2. new Function(参数1, 参数2, functionBody)

    1. Function函数的最后一个参数functionBody就是函数字符串.这里的字符串会被变成js代码成为函数体
    2. functionBody前面的参数都是最终函数的参数.
  3. with语句

        var obj = {name: "lifei", age: 18};with(obj) {var a = name; // "lifei"var age = age; // 18}

    在with语句中可以用变量直接获取obj对象上的属性.就好像把window换成了obj一样.可以直接访问他的属性.用在template函数中可以让拼接的字符串更加的清晰.但是with语句执行缓慢.慎用.

  4. 用来匹配js代码的正则表达式: /<%=\s([^%>]+)\s%>/g

    1. g: 全局匹配
    2. <%= : 用"<%="开头
    3. \s* : 不定数量的空格
    4. [^%>] : 除了"%>"以外的其他字符
    5. () : 子表达式

详解

因为有Function函数的存在.我们可以拼接一个函数字符串来生成函数.对源字符串进行处理.所以我们的主要问题就是用String.replace()拿到模板里的js代码.再和源字符串一起拼接成一个函数字符串.再用new Function()生成函数,处理字符串.生成最后的结果.比如:
```var str = "<span>name</span>"var obj = {name: "李飞"}
```
这两个参数我们最后要生成的函数字符串是:
```"var tmp = \"\"; with(obj){tmp ='<span>name</span>';}return tmp;"
``````
var template = (function() { var cache = {};return function(obj, str) {//判断strif (!typeof str === "string") {return;}//懒加载var compile = cache[str]if (!cache[str]) {var template = str.replace(/<%=\s*([^%>]+)\s*%>/g, function() {//arguments拿到正则中([^%>]+)匹配到的,js代码;var k = arguments[1]//拼接,这里最麻烦var tm =  "';" + k  + " tmp+='"return tm;})//因为js的执行代码和从对象中取数据的代码格式不一样.所以要匹配两次..replace(/\$\{\s*([^\}]+)\s*\}/g, function() {var k = arguments[1]var tm = "' +" + k+ "+'";return tm;})//拼接函数代码template = "var tmp = \"\"; with(obj){tmp ='" + template + "';}return tmp;"console.log("template")//生成函数.compile = new Function("obj", template)}//返回值return compile(obj)}
})()

```

转载于:https://www.cnblogs.com/bridge7839/p/8099019.html

template模板函数相关推荐

  1. C++ STL学习笔记 : 1. template 模板函数

    本篇文章是学习C++ STL库的第一篇笔记,主要记录了使用template关键字创建模板函数的方法. 下面用一个非常简单的例子解释模板函数的用法 : #include <iostream> ...

  2. 第六章-template模板

    第六章-template模板 文章目录 第六章-template模板 函数模板 类模板 函数模板 函数模板可以用来创建一个通用功能的函数,以支持多种不同形参,进一步简化重载函数的函数体设计 函数定义的 ...

  3. C++中函数模板template和函数参数为指针,且有返回值的结合使用

    1 #include<iostream> 2 using namespace std; 3 // 利用模板函数计算一个表达式 4 template<class Type> 5 ...

  4. c++ template笔记(1)模板函数

    1.定义函数模板 template <typename T> inline T const& max (T const& a, T const& b) {// if ...

  5. C++ and Java template class and function 模板类和模板函数

    在C++和Java的泛式编程中,模板template的使用是必不可少的,但是Java中没有template关键字,所以两者的写法还是有些许区别的,请参见如下代码: Java的模板 // Java pu ...

  6. 简述类模板函数模板template (typename T)

    相信很多刚入门c++的同学在学数据结构或者查看大佬的代码中,我们都会看到: template <typename T> 类模板; template<typename T> cl ...

  7. [转]C++函数模板与模板函数

    1.函数模板的声明和模板函数的生成 1.1函数模板的声明 函数模板可以用来创建一个通用的函数,以支持多种不同的形参,避免重载函数的函数体重复设计.它的最大特点是把函数使用的数据类型作为参数. 函数模板 ...

  8. 泛函编程—模板函数_类模板

    函数业务逻辑一样,只是函数参数类型不同 函数模板的本质:类型参数化--泛型编程 语法: template <typename T> template <class T1,class ...

  9. ytu 1057: 输入两个整数,求他们相除的余数(带参的宏 + 模板函数 练习)

    1057: 输入两个整数,求他们相除的余数 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 177  Solved: 136 [Submit][Stat ...

最新文章

  1. div布局的几点体会
  2. Content-Type一览
  3. 微软风格的CSS横向菜单
  4. python lock_python多线程Lock和RLock的区别
  5. HDU 4027 Can you answer these queries?(线段树/区间不等更新)
  6. 第8章 函数探索
  7. hive 两个没有null指定的表左关联的结果有null_Hive企业级调优表的优化
  8. 清华同方计算机教程,清华同方电脑u盘重装系统win10教程
  9. 【CC2530入门教程-01】CC2530微控制器开发入门基础
  10. DDOS---低轨道离子炮具体使用
  11. 子网掩码以及网络地址、主机地址、广播地址
  12. Wireshark抓取网络聊天
  13. 英语背单词有用吗_英语背单词真的有用吗?
  14. bios+mbr方式以及gpt+uefi方式安装win10和ubuntu18.10
  15. C语言布斯乘法算法,布斯Booth算法带符号位的乘法verilog语言实现booth算法
  16. 计算机软考难吗?如何通过?
  17. 创业,I have a dream
  18. 程控仪器标准命令SCPI
  19. 【项目精选】银行柜员业务绩效考核系统的设计与实现
  20. 硬盘IDE AHCI模式的区别

热门文章

  1. 使用HTML注释标签,超详细的HTML !–…– 注释标签使用实例.pdf
  2. python数据加载常规教程_Python加载数据的5种不同方式(收藏)
  3. 2018厦门大学计算机技术分数线,厦大录取分数线2018 各省最新录取情况
  4. expect脚本教程_Expect脚本SSH示例教程
  5. python 并发_Python bin()
  6. powermock私有字段_使用PowerMock的EasyMock私有方法模拟
  7. mac apache 日志_Mac OS X中的Apache日志文件并进行分析
  8. kotlin 循环_Kotlin控制流–否则,用于循环,同时,范围
  9. web前端面试:不做面试“海王”,一份资料就可成功上岸!
  10. Java经典基础面试题