Hi,

> I found instanceof also to work for me.

`instanceof` is great and useful in many (most?) situations, but you
do have to be careful in some edge cases, particularly if you're
writing a library, like Prototype (but not usually if you're only
*using* a library). Basically, `instanceof` checks to see if the
instance was created by a specific constructor function, e.g.:

    var t = new Template(...);
    alert(a instanceof Template); // "true"

The issue is that if you're working in a multiple-window environment
(frames, iframes), you might receive a template `t` (for instance)
from another window, in which case `t instanceof Template` will return
`false` -- because `t` wasn't created by *that* window's `Template`,
it was created by a *different* window's `Template`. And in most cases
you don't care, you just want to know whether it's a Template-like-
thing so you can use it. That's where feature checking (duck typing)
comes in.

You don't actually need multiple windows for this to come up, but
that's the most common way in browser apps. You have to be doing
esoteric things for it to come up otherwise.

The ways I test for this kind of thing are:

1. Feature-testing: What does the consumer *really* need the provided
thing to provide? Okay, test for that, then use it if there.

2. `instanceof`: If I know I'm working in a single-window and non-
esoteric situation.

3. For JavaScript's built-in objects, a combination of `typeof` and
the `Object.prototype.toString.call`. Details below.

`typeof` is fast but fairly limited. It basically tells you whether
something is a primitive or an object, and if it's a primitive it
tells you what kind, but for all objects other than functions, it just
says "object". So:

    alert(typeof "testing");             // "string", but:
    alert(typeof new String("testing")); // "object"

(And similar for numbers and booleans.) But it's useful for, say,
determining if something is a function -- and that's exactly what
prototype's `Object.isFunction` uses.

The `Object.prototype.toString.call` trick is slower, but more useful
for differentiating what kind of object you have -- but sadly, only if
the object is one created by one of the built-in JavaScript
constructor functions like Date or String, not our own constructor
functions. The return value of the `Object` prototype's `toString`
function is defined in the standard for all the built-in constructor
functions (Array, Date, etc.): It returns "[object ___]" where ___ is
the constructor function name. So:

    alert(Object.prototype.toString.call(new Date()));   // "[object
Date]"
    alert(Object.prototype.toString.call(function(){})); // "[object
Function]"
    alert(Object.prototype.toString.call([]));           // "[object
Array]"

...etc. It also coerces its argument into an object if it can before
checking, which is useful for strings, numbers, and booleans -- you
get "[object String]" even when checking a primitive string. This is
what Prototype's `Object.isArray` uses, since Prototype is frequently
used in frames and such and so something can be an Array without being
`instanceof Array`. But sadly for our own constructor functions:

    alert(Object.prototype.toString.call(new Template("foo"))); //
"[object Object]"

Ah, well...

FWIW,
--
T.J. Crowder
Independent Software Consultant
tj / crowder software / com
www / crowder software / com


On Sep 5, 8:25 am, Richard Quadling <rquadl...@gmail.com> wrote:
> On 4 September 2010 07:54, Johan Arensman <johanm...@gmail.com> wrote:
>
>
>
>
>
> > Feature checking is usually done by checking for a specific method or
> > attribute on the object.
> > For a template you can check for the evaluate method:
> > if(MyObject.evaluate) {
> >   // it's a template
> > }
>
> > On Wed, Sep 1, 2010 at 5:20 PM, Richard Quadling <rquadl...@gmail.com>
> > wrote:
>
> >> Hi.
>
> >> I can't find a way to determine the type of object being supplied to a
> >> function.
>
> >> I can check if it is a string ...
>
> >> if (Object.isString(param)) {
> >>  var tmpl = new Template(param);
> >> } else if (Object.type(param) = 'Template') {
> >>  var tmpl = param;
> >> }
>
> >> sort of thing.
>
> I found instanceof also to work for me.
>
> --
> Richard Quadling
> Twitter : EE : Zend
> @RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY

-- 
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptacul...@googlegroups.com.
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.

Reply via email to