javascript - 如何为js的eval指定一个object作为上下文?
大家讲道理
大家讲道理 2017-04-10 14:35:10
[JavaScript讨论组]

需要实现一个很简易的js模板.
现在有以下函数:

  function compile(tpl, scope){
    return tpl.replace(/\{\{([\s\S]+?)\}\}/g, function(caught, content){
      var compiled;
      try{
        compiled = eval.call(scope, content);
      }catch(e){
        compiled = caught;
        console.error(e);
      }finally{
        return compiled;
      }
    });
  }

调用compile时
假设tpl为

<p> {{ uploadMaxSize / 1024 / 1024 }}M </p>

以及scope为

{  uploadMaxSize : 1048576  }

而运行结果如下
uploadMaxSize is not defined

这是为何
(另外, 请不要改变论点, 这边的问题是"如何指定一个object作为eval的上下文")

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

全部回复(3)
黄舟

于是...

function compile(tpl, scope){
  return tpl.replace(/\{\{([\s\S]+?)\}\}/g, function(caught, content){
    try{
      return (new Function('with(this){return ' + content + '}')).call(scope);
    }catch(e){
      console.error(e);
      return caught;
    }
  });
}

strict mode 也可以用with咯

PHP中文网
function compile(tpl, scope) {
  tpl = tpl.replace(/\{%\s*(.*?)\s*%\}/g, function(_, k) {
    for (var i in scope) {
      this[i] = scope[i];
    }
    return eval(k);
  });
  return tpl.replace(/\{\{\s*(.*?)\s*\}\}/g, function(_, k) {
    return scope[k];
  });
}

应该这样写吧。
建议把模板填充和模板计算分开。分别用 {{}} 和 {%%}。

巴扎黑

直接写成:

compiled = scope[content];

不行吗?
还有你的模版是不是应该改成:

<p> {{ uploadMaxSize }}M </p>
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号