• 深入浅出node模板解析错误escape is not a function


    深入浅出node模板解析错误escape is not a function

    操作

    var escape = function (html) {
      return String(html)
        .replace(/&(?!\w+;)/g, '&')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
    }
    
    var complie = function (str) {
    	console.log(str)
      var tpl = str.replace(/<%=([\s\S]+?)%>/g, function (match, code) {
        // 转义
        return "' + escape(" + code + ") + '"
      }).replace(/<%-([\s\S]+?)%>/g, function (match, code) {
        // 正常输出
        return "' + " + code + " + '"
      }).replace(/<%([\s\S]+?)%>/g, function (match, code) {
        return "';\n" + code + "\n    tpl += '"
      }).replace(/\'\n/g, '\'')
      .replace(/\n\'/gm, '\'')
    
      console.log('----------代码替换模板----------')
      console.log(tpl)
      tpl = "tpl = '" + tpl + "'"
      tpl = tpl.replace(/''/g, '\'\\n\'')
      tpl = '  var tpl = ""\n  with (obj || {}) {\n  ' + tpl + '\n  }\n  return tpl'
      return new Function('obj', 'escape', tpl)
    }
    
    var render = function(complie, data) {
    	console.log('----------构造函数----------')
    	console.log(complie.toString())
    	console.log('----------运行函数----------')
    	return complie(data)
    }
    
    var tpl = [
      '<%  if (obj.user) {  %>',
        '<h2><%=user.name%></h2>',
      '<%  } else {  %>',
        '<h2>匿名用户</h2>',
      '<%  }  %>'].join('\n')
    
    console.log('----------模板----------')
    console.log(tpl)
    console.log(render(complie(tpl), {user: {name: 'Jackson Tian'}}))
    //console.log('\n\n')
    //console.log(render(complie(tpl), {}))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    异常信息

    TypeError: escape is not a function
        at eval (eval at complie (F:\workspace\javascript workspace\plNode\prj8_5_4_2\src\template4.js:27:10), <anonymous>:7:21)
        at render (F:\workspace\javascript workspace\plNode\prj8_5_4_2\src\template4.js:34:9)
        at Object.<anonymous> (F:\workspace\javascript workspace\plNode\prj8_5_4_2\src\template4.js:49:13)
        at Module._compile (internal/modules/cjs/loader.js:1085:14)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
        at Module.load (internal/modules/cjs/loader.js:950:32)
        at Function.Module._load (internal/modules/cjs/loader.js:790:12)
        at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
        at internal/main/run_main_module.js:17:47
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    分析原因

    • escape不是函数,因为 return new Function(‘obj’, ‘escape’, tpl) 语句中 ‘escape’是函数,complie(data, escape) 调用的时候需要传递 escape函数,否则找不到escape函数

    解决方法

    方法一
    • 调用时,传递escape函数
    complie(data, escape)
    
    • 1
    方法二
    • 自己调用自己时,传递escape函数
    complie.call(complie, data, escape)
    # 或者
    complie.call(this, data, escape)
    
    • 1
    • 2
    • 3

    完整代码

    var escape = function (html) {
      return String(html)
        .replace(/&(?!\w+;)/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
    }
    
    var complie = function (str) {
    	console.log(str)
      var tpl = str.replace(/<%=([\s\S]+?)%>/g, function (match, code) {
        // 转义
        return "' + escape(" + code + ") + '"
      }).replace(/<%-([\s\S]+?)%>/g, function (match, code) {
        // 正常输出
        return "' + " + code + " + '"
      }).replace(/<%([\s\S]+?)%>/g, function (match, code) {
        return "';\n" + code + "\n    tpl += '"
      }).replace(/\'\n/g, '\'')
      .replace(/\n\'/gm, '\'')
    
      console.log('----------代码替换模板----------')
      console.log(tpl)
      tpl = "tpl = '" + tpl + "'"
      tpl = tpl.replace(/''/g, '\'\\n\'')
      tpl = '  var tpl = ""\n  with (obj || {}) {\n  ' + tpl + '\n  }\n  return tpl'
      return new Function('obj', 'escape', tpl)
    }
    
    var render = function(complie, data) {
    	console.log('----------构造函数----------')
    	console.log(complie.toString())
    	console.log('----------运行函数----------')
    	return complie(data, escape)
    	// 等价于
    	//return complie.call(this, data, escape)
    }
    
    var tpl = [
      '<%  if (obj.user) {  %>',
        '<h2><%=user.name%></h2>',
      '<%  } else {  %>',
        '<h2>匿名用户</h2>',
      '<%  }  %>'].join('\n')
    
    console.log('----------模板----------')
    console.log(tpl)
    console.log(render(complie(tpl), {user: {name: 'Jackson Tian'}}))
    //console.log('\n\n')
    //console.log(render(complie(tpl), {}))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
  • 相关阅读:
    数学基础从高一开始1、集合的概念
    建筑建材行业经销商协同系统解决方案:赋能企业构建核心竞争力
    VR全景算不算好的创业项目?有哪些特性?
    990-27产品经理:What is IT risk? 什么是IT风险?
    STM32F4之系统滴答定时器
    征集 |《新程序员》专访Python之父,你最想问什么?
    Cannot connect to the Docker
    电场与磁场中的物理量
    Jmeter怎么实现接口关联?
    释放数据的潜力:用梯度上升法解锁主成分分析(PCA)的神奇
  • 原文地址:https://blog.csdn.net/xzlAwin/article/details/125623463