使用'use strict'和underscore.js的问题 [英] Issue with with 'use strict' and underscore.js

查看:132
本文介绍了使用'use strict'和underscore.js的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've written an app using Yeoman and backbone.js. At the top of every js file I have specified 'use strict'; and when I run my grunt tasks jshint does not encounter any errors.

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

I am able to build my app with grunt without issue however when I try to run the uglified js I get the following error:

未捕获的SyntaxError:严格模式代码可能不包含with语句

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

I've searched the code base and the only things using a with statement is underscore.

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

I'm new to strict mode so I'm not sure how I can resolve this issue. Can I not use strict mode anywhere that I use an underscorejs function?

谢谢。

编辑:

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

Given the code samples below (shortened for brevity). How could I change it to resolve this issue.

'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中的

in MyView.ejs

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

编辑2:

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

Using @mu is too shorts's answer below I discovered that the best way to resolve the calls to _.template that were giving me grief was change my grunt-JST task as follows:

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

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

And then change each of my templates to use the <%= data.templateVariable %> format.

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

May not apply to others, but I ran into this issue using Yeoman with Grunt and a Backbone generator so I can't be the only one.

推荐答案

下划线的 _。template 使用 以允许<%= pancakes等内容%> 要解析为 obj.pancakes 。如果您查看 _。template ,你会发现:

Underscore's _.template uses with internally to allow things like <%= pancakes %> to be resolved to obj.pancakes. If you look inside _.template, you'll find this:

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

这是具有的攻击性来自的地方。如果您使用的是JST样式预编译模板,那么 source 就是您在 JST 对象中最终得到的内容这使带的use strict的范围内可见。请注意那里的 settings.variable 文档说:

That's where the offensive with comes from. If you're using JST style precompiled templates, that source is what you'll end up with inside your JST object and that makes the withs visible within the scope of "use strict". Notice that settings.variable in there? The documentation says:


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

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"


所以你可以压制编译模板时,使用变量选项 s;当然,这也意味着你必须重写所有<%= ...%> 部分模板,以匹配变量选项必须说明(这也应该加快你的模板速度,因此它可能值得这样做。)

So you can suppress the withs by using the variable option when compiling the templates; of course, this also means that you'll have to rewrite all the <%= ... %> parts of your templates to match what the variable option has to say (this should also speed up your templates so it might be worth it just for that).

在你的例如,您将模板更改为:

In your case, you'd change the template to this:

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

然后你需要更改 _。template 用于编译模板的调用如下所示:

and then you'd need to change the _.template call that is used to compile the templates to look like this:

var compiled_template = _.template(raw_template, null, { variable: 'data' });

您不必使用数据当然,你只需要在模板和 _。模板调用中使用相同的东西。

You don't have to use data of course, you just need to use the same thing in both the templates and the _.template call.

我不知道你如何改变你的设置如何调用 _。template 但它应该不那么困难。我想你可以将补丁 _。template 作为最后的手段来获得变量的默认值。

I don't know how you'd change how your set up calls _.template but it shouldn't be that difficult. I suppose you could monkey patch _.template to have a default value for variable as a last resort.

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

Here's a simple demo that should illustrate what's going on: http://jsfiddle.net/ambiguous/Az8QM/

或者,如果我们看一下 use strict是作用域,我们将看到:

Alternatively, if we look at how "use strict" is scoped, we'll see that:


严格模式适用于整个脚本个别函数

所以你可以用这样的方式本地化你的严格性:

So you can localize your strictness with something like this:

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

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

You could also use two JavaScript files instead of just one:


  1. 一个非模板JavaScript,其中<​​code>use strict已启用。

  2. 第二个只有你的 JST ,这个 use strict

  1. One for your non-template JavaScript with "use strict" enabled.
  2. A second one with just your JST, this one would not "use strict".

这篇关于使用'use strict'和underscore.js的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆