2

我希望能够检测到我正在查看的对象是_.template的一个实例,就像我可以检查Backbone Models/Collections/Views一样。检测instanceof下划线模板

例如:

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,目前。

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

回答

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返回的功能:

属性可在方便的预编译编译模板函数。

所以,你可以用instanceoftypeof结合in收紧事情:

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

这两项应该是true如果t_.template出来(但反之,当然,不一定是真实的)。

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

至于第二个问题去,我想不出你怎么能有t()t instanceof T都工作时TFunction(我可能会错过一些东西很明显,当然,但搞乱使用本地类型通常在JavaScript中不能很好地工作)。如果你想说:

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

,而不是t(...)那么这将是容易的,但它会与知道下划线模板的一切格格不入。

3

如果你看看source of the _.template method,你会发现你在这里吠叫错误的树 - 下划线没有实例化一个对象,它通过建立一个源代码字符串为你构建一个新的函数并用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 
+1

如何安全/可靠是惹与['构造函数'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor)虽然?像'template.is_underscore_template'可能是一个更好的主意。 –

+0

嗯,在这种情况下根本就不重要,而且OP似乎想要一些惯用的东西。 – nrabinowitz

+0

它*不应该*重要,但它感觉就像用棍子戳一个马蜂窝。 –