我希望能够检测出我正在查看的对象是否是_.template的一个实例,就像检查Backbone模型/集合/视图一样。
例如:
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中,如果它当前是字符串而不是Underscore模板。
然而,我的2个问题 -
我想知道目前是否有办法检查instanceof _.template。
如果没有,扩展模板原型链以进行此检查是否过于昂贵?除非它慢得多,否则这似乎是下划线中的(次要)错误。
答案 0 :(得分:3)
_.template
只返回一个普通的旧函数,而不是特定的任何实例,而不是你应该用new
的东西,它只是一个简单的函数。
如果我们看一下the source(我强烈推荐这样的问题),你会发现_.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
will add a source
property:
source 属性在编译的模板函数上可用,以便于预编译。
因此,您可以将in
与instanceof
或typeof
相结合,从而收紧工作:
typeof t === 'function' && 'source' in t
t instanceof Function && 'source' in t
如果true
t
来自_.template
,那么这两者都应为t()
(但反过来,当然不一定如此)。
演示:http://jsfiddle.net/ambiguous/a2auU/
就第二个问题而言,当t instanceof T
不是T
时,我无法想到Function
和var t = _.template(s);
var h = t.exec(...);
如何工作(我可以当然缺少一些显而易见的东西,但是在使用原生类型时通常不能很好地解决这个问题。如果你想说:
t(...)
而不是{{1}}那么它很容易,但它与所有了解Underscore模板的内容不兼容。
答案 1 :(得分:3)
如果你看一下source of the _.template
method,你会发现你在这里咆哮错误的树 - 下划线没有实例化一个_.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