javascript - 'use strict' 和 underscore.js 问题

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

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

我可以毫无问题地使用 grunt 构建我的应用程序,但是当我尝试运行丑陋的 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 生成器时遇到了这个问题,所以我不是唯一的问题。

最佳答案

下划线的 _.template使用 with 在内部允许类似 <%= pancakes %> 的事情待解决obj.pancakes .如果你look inside _.template ,你会发现这个:

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

这就是攻势with来自。如果您使用的是 JST 风格的预编译模板,那么 source是你最终会在你的 JST 中得到的东西对象,这使得 with"use strict"范围内可见.注意 settings.variable在那里? The documentation说:

By default, template places the values from your data in the local scope via the with statement. However, you can specify a single variable name with the variable setting. This can significantly improve the speed at which a template is able to render.

_.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 variable 的默认值作为最后的手段。

这是一个简单的演示,可以说明发生了什么:http://jsfiddle.net/ambiguous/Az8QM/


或者,如果我们看看如何 "use strict" is scoped ,我们会看到:

Strict mode applies to entire scripts or to individual functions.

所以你可以用这样的东西来本地化你的严格:

(function() {
    "use strict";
    // All your non-JST JavaScript goes here.
})();
// Append your JST out here.

你也可以使用两个 JavaScript 文件而不是一个:

  1. 一个用于非模板 JavaScript,带有 "use strict"启用。
  2. 第二个只有你的 JST , 这个不会 "use strict" .

关于javascript - 'use strict' 和 underscore.js 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18679422/

相关文章:

javascript - 从 $(document).ready 调用 Jquery 函数耗时太长 - IE 弹出 "stop running script"对话框

javascript - 如何合并两个复杂的 JSON 对象,仅具有唯一或不同的值仅显示在结果数组中

javascript - 从所有中删除相应的 Li

javascript - 合并两个对象并在冲突时覆盖值

javascript - 比较一组对象中的对象

html - 咕噜服务 :dist using local file paths

angularjs - StrongLoop Loopback Yeoman Angular

JavaScript:switch 语句未在文本框中设置值

javascript - underscore.js _.where 用于字符串和对象

angularjs - karma 报应/ Jasmine /PhantomJs : undefined is not a constructor