当前位置:网站首页>深入浅出node模板解析错误escape is not a function

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

2022-07-06 04:06:00 xzlAwin

深入浅出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), {}))

异常信息

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

分析原因

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

解决方法

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

完整代码

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), {}))
原网站

版权声明
本文为[xzlAwin]所创,转载请带上原文链接,感谢
https://blog.csdn.net/xzlAwin/article/details/125623463