2

我希望能够检测我正在查看的对象是否是 _.template 的实例,就像我可以检查主干模型/集合/视图一样。

例如:

var newView = new Backbone.View();
newView instanceof Backbone.View //true

//How I usually use template
var test = _.template("test");
test instanceof _.template //false

//When I would actually expect a successful instanceof check
var test2 = new _.template("test");
test2 instanceof _.template //false

我改用这个:

typeof test == "function"

对于我的情况,这基本上已经足够了,因为如果模板当前是字符串而不是下划线模板,我只是将模板包装在 _.template 中。

但是,我的 2 个问题 -

我想知道目前是否有办法检查 instanceof _.template。

如果不是,扩展模板原型链以允许此检查是否过于昂贵?除非它慢得多,否则这似乎是 Underscore 中的一个(小)错误。

4

2 回答 2

3

_.template只是返回一个普通的旧函数,而不是任何特定的实例,也不是你应该使用的东西new,它只是一个简单的函数。

如果我们查看源代码(对于此类问题,我强烈建议您使用它),您会发现 的结构_.template或多或少是这样的:

// A bunch of stuff to convert the template to JavaScript code
// which is combined with some boiler plate machinery and left
// in `source`
// ...
render = new Function(settings.variable || 'obj', '_', source);
template = function(data) { return render.call(this, data, _); };
return template;

所以你得到_.template(str)的只是一个匿名函数,没有设置特殊的原型链,唯一常用的instanceof就是Function. 在这种情况下询问是否t instanceof Function真的不是非常有用,我认为这不会做任何typeof t == 'function'尚未做的事情。

但是,将向返回的函数_.template添加一个source属性:

source属性在已编译的模板函数上可用,以便于预编译。

in所以你可以通过结合instanceofor来收紧事情typeof

typeof t === 'function' && 'source' in t
t instanceof Function  && 'source' in t

true如果t来自的话,这两者都应该是_.template(但反过来,当然,不一定是真的)。

演示:http: //jsfiddle.net/ambiguous/a2auU/

就第二个问题而言,我想不出你如何拥有t()并且t instanceof T两者都可以在T没有的情况下工作Function(当然,我可能会遗漏一些明显的东西,但在 JavaScript 中弄乱本机类型通常不会那么好)。如果你想说:

var t = _.template(s);
var h = t.exec(...);

而不是t(...)这样,它会很容易,但它会与了解下划线模板的所有内容不兼容。

于 2013-08-23T21:41:21.790 回答
3

如果你查看方法的源代码_.template,你会发现你在这里找错了树——下划线不是实例化一个_.template对象,它是通过构建一串源代码并编译来为你构建一个新函数它与new Function(). 所以你使用的模板函数是一个新的匿名函数,而不是任何东西的实例。

如果您真的想要一种识别模板的方法,我建议您装饰该_.template函数以添加某种标志 - 也许作为一个constructor属性:

var originalMethod = _.template;
_.template = function() {
    var template = originalMethod.apply(_, arguments);
    template.constructor = _.template;
    return template;
}

var t = _.template('Foo <%= bar %>');
t({ bar: "baz" }); // "Foo baz"
t.constructor === _.template;  // true
于 2013-08-23T21:43:20.810 回答