使用'use strict'和underscore.js的问题

时间:2013-09-08 01:09:03

标签: javascript underscore.js yeoman underscore.js-templating

我使用Yeoman和backbone.js编写了一个应用程序。在每个js文件的顶部,我指定了'use strict';,当我运行我的grunt任务时,jshint不会遇到任何错误。

我可以使用grunt构建我的应用程序而没有问题但是当我尝试运行uglified js时出现以下错误:

Uncaught SyntaxError: Strict mode code may not include a with statement

我搜索了代码库,使用with语句的唯一内容是下划线。

我是严格模式的新手,所以我不确定如何解决这个问题。我可以在任何使用underscorejs函数的地方使用严格模式吗?

感谢。

修改

考虑下面的代码示例(为简洁起见,缩短了)。我怎么能改变它来解决这个问题。

'use strict';

/*global, Backbone, JST*/

var MyView = Backbone.View.extend({

    template: JST['app/scripts/templates/MyView.ejs'],

    initialize: function()
    {
        this.render();
    },

    render : function()
    {
        this.$el.html(this.template(this.templateVariables()));
        return this;
    },

    templateVariables: function()
    {
        return {var1 : 'Hello', var2 : 'World'};
    }
});
MyView.ejs中的

<p><%= var1 %><%= var2 %>!</p> //<p>Hello World!</p>

编辑2:

在下面使用@mu太简短的答案我发现解决给我悲伤的_.template调用的最佳方法是改变我的grunt-JST任务如下:

jst: {
        compile: {
            options:
            {
                templateSettings:
                {
                    variable: 'data'
                }
            },
            files: {
                '.tmp/scripts/templates.js': ['<%= yeoman.app %>/scripts/templates/*.ejs']
            }
        }
    },

然后更改我的每个模板以使用<%= data.templateVariable %>格式。

可能不适用于其他人,但我使用Yeoman和Grunt以及Backbone生成器遇到了这个问题,所以我不能成为唯一一个。

1 个答案:

答案 0 :(得分:18)

下划线的_.template在内部使用with,可以将<%= pancakes %>之类的内容解析为obj.pancakes。如果你look inside _.template,你会发现:

if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';

这就是攻击性with的来源。如果您使用的是JST样式的预编译模板,那么source就会在JST对象中结束,这使得with在{{1}的范围内可见}}。请注意"use strict"在那里? The documentation说:

  

默认情况下,模板会通过settings.variable语句将数据中的值放在本地范围内。但是,您可以使用变量设置指定单个变量名称。这可以显着提高模板渲染的速度。

with

因此,您可以在编译模板时使用_.template("Using 'with': <%= data.answer %>", {answer: 'no'}, {variable: 'data'}); => "Using 'with': no" 选项来禁止with;当然,这也意味着您必须重写模板的所有variable部分以匹配<%= ... %>选项所说的内容(这也应该加快您的模板速度,因此它可能值得它就是为了那个)。

在您的情况下,您将模板更改为:

variable

然后你需要更改用于编译模板的<p><%= data.var1 %><%= data.var2 %>!</p> //<p>Hello World!</p> 调用,如下所示:

_.template

当然,您不必使用var compiled_template = _.template(raw_template, null, { variable: 'data' }); ,只需在模板和data调用中使用相同的内容。

我不知道您如何更改设置调用_.template的方式,但它不应该那么困难。我想你可以将补丁_.template设为_.template的默认值作为最后的手段。

这是一个简单的演示,应该说明正在发生的事情:http://jsfiddle.net/ambiguous/Az8QM/


或者,如果我们查看"use strict" is scoped的方式,我们会看到:

  

严格模式适用于整个脚本各个功能

所以你可以通过以下方式将你的严格程度本地化:

variable

您还可以使用两个JavaScript文件而不只是一个:

  1. 一个用于启用了(function() { "use strict"; // All your non-JST JavaScript goes here. })(); // Append your JST out here. 的非模板JavaScript。
  2. 第二个只有你的"use strict",这个 JST