JavaScript Detect instanceof Underscore template

I would like to be able to detect if an object I'm looking at is an instance of _.template, the same way I can check for Backbone Models/Collections/Views.

for example:

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

I'm resorting to this instead:

typeof test == "function"

This is basically good enough for my circumstances, since I'm just wrapping my template in _.template if it's currently a string instead of an Underscore template.

However, my 2 questions -

I'm wondering if there's a way to check instanceof _.template, currently.

If not, is it prohibitively expensive to extend the template Prototype chain to allow this check? Unless it's much slower, this seems like a (minor) fault in Underscore.

Answer:1

_.template simply returns a plain old function, not an instance of anything in particular and not something that you're supposed to use with new, it is just a simple function.

If we have a look at the source (which I strongly recommend for questions like this), you'll see that the structure of _.template is more or less like this:

// 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;

So the thing you get back from _.template(str) is just an anonymous function, there's no special prototype chain set up and the only common thing to use with instanceof is Function. Asking if t instanceof Function really isn't terribly useful in this case, I don't think that will do anything that typeof t == 'function' isn't doing already.

However, _.template will add a source property to the returned function:

The source property is available on the compiled template function for easy precompilation.

So you could tighten things up by combining in with instanceof or typeof:

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

Both of those should be true if t came from _.template (but the converse is, of course, not necessarily true).

Demo: http://jsfiddle.net/ambiguous/a2auU/

As far as the second question goes, I can't think of how you can have t() and t instanceof T both work when T is not Function (I could be missing something obvious of course but messing with native types generally doesn't work out that well in JavaScript). If you wanted to say:

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

instead of t(...) then it would be easy but it would be incompatible with everything that knows about Underscore templates.

Answer:2

I'm using the Google Book Viewer API to show book previews based on metadata found on the page. This is in a system I don't control, although I can append scripts and markup. Only some pages contain ...

I'm using the Google Book Viewer API to show book previews based on metadata found on the page. This is in a system I don't control, although I can append scripts and markup. Only some pages contain ...

  1. google book viewer
  2. google book ngram viewer
  3. google labs book ngram viewer

I set tooltip option enabled = FALSE. I want change it to TRUE when user clicks on point. How can I do it? series : [{ data : data, dataGrouping: { enabled: ...

I set tooltip option enabled = FALSE. I want change it to TRUE when user clicks on point. How can I do it? series : [{ data : data, dataGrouping: { enabled: ...

  1. highcharts change options dynamically
  2. highcharts change options after render
  3. highcharts change options
  4. highcharts change options and redraw
  5. highcharts change export options
  6. highcharts change chart options

I can't make the script to create random amount of divs. In this specific example between 5 and 20. The problem is in the for loop maybe? The function that generates random numbers is working ...

I can't make the script to create random amount of divs. In this specific example between 5 and 20. The problem is in the for loop maybe? The function that generates random numbers is working ...

  1. generate random number python
  2. generate random number java
  3. generate random number javascript
  4. generate random number c++
  5. generate random number excel
  6. generate random number in r
  7. generate random number matlab
  8. generate random number js
  9. generate random number between two numbers
  10. generate random number numpy
  11. generate random number php
  12. generate random number in range
  13. generate random number in range java
  14. generate random number sql
  15. generate random number swift
  16. generate random number bash
  17. generate random number stata
  18. generate random number ruby
  19. generate random number google sheets
  20. generate random number python numpy

I am trying to implement drag and drop rows with in same table using html5, but I would like to restrict the drop area to few rows instead of whole table. Code : <table id="visibletable" class="...

I am trying to implement drag and drop rows with in same table using html5, but I would like to restrict the drop area to few rows instead of whole table. Code : <table id="visibletable" class="...