isFunction (Code Worth Recommending Project)

Discussion in 'Javascript' started by David Mark, Dec 8, 2007.

  1. David Mark

    David Mark Guest

    I see the "When is a function not a function" thread has flared up
    again.

    This is what I use to test parameters that can be Functions or
    Objects. It does return the expected result for callable host objects
    (at least the ones I tested.) None of the functions it supports are
    expected to receive those as parameters. The second part of the test
    is a little ambiguous in this regard (for browsers that do not support
    call), so it is best to exclude callable host objects as a rule.

    var isFunction = function(o) {
    return typeof(o) == 'function' && (!Function.prototype.call ||
    typeof(o.call) == 'function');
    };
     
    David Mark, Dec 8, 2007
    #1
    1. Advertising

  2. David Mark wrote:
    > I see the "When is a function not a function" thread has flared up
    > again.
    >
    > This is what I use to test parameters that can be Functions or
    > Objects. It does return the expected result for callable host objects
    > (at least the ones I tested.) None of the functions it supports are
    > expected to receive those as parameters. The second part of the test
    > is a little ambiguous in this regard (for browsers that do not support
    > call), so it is best to exclude callable host objects as a rule.
    >
    > var isFunction = function(o) {
    > return typeof(o) == 'function' && (!Function.prototype.call ||
    > typeof(o.call) == 'function');
    > };


    isFunction() will return `false' where Function.prototype.call is not
    supported and the object has no `call' property, even though the argument
    referred to a Function object. That is the case in JavaScript before
    version 1.3 as supported by Netscape Navigator, version 4.05 and earlier,
    and, more important, JScript before version 5.5 as supported e.g. by
    Microsoft Internet Explorer for Windows NT, version 5.01 and earlier.

    The argument may be an unqualified reference in which case calling this
    testing method fails if the identifier of that reference was not defined before.

    There is no point in assigning a function object created by a function
    expression in the initialization of a variable instead of a simple function
    declaration, unless that code is part of a conditional execution block.

    `typeof' is an operator, not a method, and should be written accordingly.


    PointedEars
    --
    Prototype.js was written by people who don't know javascript for people
    who don't know javascript. People who don't know javascript are not
    the best source of advice on designing systems that use javascript.
    -- Richard Cornford, cljs, <f806at$ail$1$>
     
    Thomas 'PointedEars' Lahn, Dec 8, 2007
    #2
    1. Advertising

  3. David Mark

    David Mark Guest

    On Dec 8, 9:33 am, Thomas 'PointedEars' Lahn <>
    wrote:
    > David Mark wrote:
    > > I see the "When is a function not a function" thread has flared up
    > > again.

    >
    > > This is what I use to test parameters that can be Functions or
    > > Objects. It does return the expected result for callable host objects
    > > (at least the ones I tested.) None of the functions it supports are
    > > expected to receive those as parameters. The second part of the test
    > > is a little ambiguous in this regard (for browsers that do not support
    > > call), so it is best to exclude callable host objects as a rule.

    >
    > > var isFunction = function(o) {
    > > return typeof(o) == 'function' && (!Function.prototype.call ||
    > > typeof(o.call) == 'function');
    > > };

    >
    > isFunction() will return `false' where Function.prototype.call is not
    > supported and the object has no `call' property, even though the argument
    > referred to a Function object. That is the case in JavaScript before


    If it is a Function then the first part of the conjunction is true.
    The second part will also be true as !Function.prototype.call will
    evaluate to true when call is not supported. So just what are you
    talking about?

    [snip]

    >
    > The argument may be an unqualified reference in which case calling this
    > testing method fails if the identifier of that reference was not defined before.


    You aren't allowed to pass anything but Function objects or Object
    objects. Those are the rules as documented. Results are not defined
    for anything else.

    >
    > There is no point in assigning a function object created by a function
    > expression in the initialization of a variable instead of a simple function
    > declaration, unless that code is part of a conditional execution block.


    The reason it is written like that is it was originally assigned as a
    method of an object.

    >
    > `typeof' is an operator, not a method, and should be written accordingly.


    That is just my personal style. I've always written it that way and I
    think it is easier to read.
     
    David Mark, Dec 8, 2007
    #3
  4. David Mark wrote:
    > On Dec 8, 9:33 am, Thomas 'PointedEars' Lahn <>
    > wrote:
    >> David Mark wrote:
    >>> I see the "When is a function not a function" thread has flared up
    >>> again.
    >>> This is what I use to test parameters that can be Functions or
    >>> Objects. It does return the expected result for callable host objects
    >>> (at least the ones I tested.) None of the functions it supports are
    >>> expected to receive those as parameters. The second part of the test
    >>> is a little ambiguous in this regard (for browsers that do not support
    >>> call), so it is best to exclude callable host objects as a rule.
    >>> var isFunction = function(o) {
    >>> return typeof(o) == 'function' && (!Function.prototype.call ||
    >>> typeof(o.call) == 'function');
    >>> };

    >> isFunction() will return `false' where Function.prototype.call is not
    >> supported and the object has no `call' property, even though the argument
    >> referred to a Function object. That is the case in JavaScript before

    >
    > If it is a Function then the first part of the conjunction is true.
    > The second part will also be true as !Function.prototype.call will
    > evaluate to true when call is not supported. So just what are you
    > talking about?


    Sorry, I have confused matters here. However, I would like to point out
    that it does not make sense to test against Function.prototype.call, be it
    in the negative direct or the positive indirect way. That the object has
    a(n *external*) `call' property has nothing to do with whether or not it is
    callable (with an argument list), having an *internal* [[Call]] method.

    >> The argument may be an unqualified reference in which case calling this
    >> testing method fails if the identifier of that reference was not defined before.

    >
    > You aren't allowed to pass anything but Function objects or Object
    > objects. Those are the rules as documented.


    That is ridiculous. One does not need to call the method if one already
    knows that the argument is a reference to a Function or Object object.

    > Results are not defined for anything else.


    Apparently you don't know what an unqualified reference is.

    >> `typeof' is an operator, not a method, and should be written accordingly.

    >
    > That is just my personal style. I've always written it that way and I
    > think it is easier to read.


    If it is also part of your personal style to have method identifiers
    followed by the argument list without whitespace, then there is a
    contradiction in it.


    PointedEars
    --
    realism: HTML 4.01 Strict
    evangelism: XHTML 1.0 Strict
    madness: XHTML 1.1 as application/xhtml+xml
    -- Bjoern Hoehrmann
     
    Thomas 'PointedEars' Lahn, Dec 8, 2007
    #4
  5. David Mark

    David Mark Guest

    On Dec 8, 11:07 am, Thomas 'PointedEars' Lahn <>
    wrote:
    > David Mark wrote:
    > > On Dec 8, 9:33 am, Thomas 'PointedEars' Lahn <>
    > > wrote:
    > >> David Mark wrote:
    > >>> I see the "When is a function not a function" thread has flared up
    > >>> again.
    > >>> This is what I use to test parameters that can be Functions or
    > >>> Objects. It does return the expected result for callable host objects
    > >>> (at least the ones I tested.) None of the functions it supports are
    > >>> expected to receive those as parameters. The second part of the test
    > >>> is a little ambiguous in this regard (for browsers that do not support
    > >>> call), so it is best to exclude callable host objects as a rule.
    > >>> var isFunction = function(o) {
    > >>> return typeof(o) == 'function' && (!Function.prototype.call ||
    > >>> typeof(o.call) == 'function');
    > >>> };
    > >> isFunction() will return `false' where Function.prototype.call is not
    > >> supported and the object has no `call' property, even though the argument
    > >> referred to a Function object. That is the case in JavaScript before

    >
    > > If it is a Function then the first part of the conjunction is true.
    > > The second part will also be true as !Function.prototype.call will
    > > evaluate to true when call is not supported. So just what are you
    > > talking about?

    >
    > Sorry, I have confused matters here. However, I would like to point out
    > that it does not make sense to test against Function.prototype.call, be it
    > in the negative direct or the positive indirect way. That the object has
    > a(n *external*) `call' property has nothing to do with whether or not it is
    > callable (with an argument list), having an *internal* [[Call]] method.


    It is not meant to return true for anything but Functions. It is not
    an isCallable function.

    >
    > >> The argument may be an unqualified reference in which case calling this
    > >> testing method fails if the identifier of that reference was not defined before.

    >
    > > You aren't allowed to pass anything but Function objects or Object
    > > objects. Those are the rules as documented.

    >
    > That is ridiculous. One does not need to call the method if one already
    > knows that the argument is a reference to a Function or Object object.


    As explained, it is for functions to test parameters, which may be
    Function objects or Object objects. The functions that call it need
    to distinguish between the two. It is not for feature detection, but
    for overloading functions (typically those that perform callbacks.)

    As I mentioned in the first post, but left out in the second, it also
    can handle host objects (including those that are callable.)

    >
    > > Results are not defined for anything else.

    >
    > Apparently you don't know what an unqualified reference is.


    I misread what you said. Of course I know what an unqualified
    reference is. Didn't we just have a long discussion about them in a
    recent thread (yesterday.) Regardless, the function does exactly what
    it is designed to do. Furthermore, this is not the first time it has
    been posted here. Go back and read the original thread (which I
    started) and perhaps you will understand the context of this one.

    As for unqualified references:

    isFunction(document) == false

    isFunction(attachEvent) == false // IE only of course, errors
    elsewhere

    Do you see what I am testing for now? Methods of host objects do not
    apply, despite the fact that they are obviously callable. Unqualified
    references to methods of host objects do not return anything different
    than qualified ones. So your point eludes me.

    >
    > >> `typeof' is an operator, not a method, and should be written accordingly.

    >
    > > That is just my personal style. I've always written it that way and I
    > > think it is easier to read.

    >
    > If it is also part of your personal style to have method identifiers
    > followed by the argument list without whitespace, then there is a
    > contradiction in it.


    An ambiguity, but not a contradiction.
     
    David Mark, Dec 8, 2007
    #5
  6. David Mark wrote:
    > On Dec 8, 11:07 am, Thomas 'PointedEars' Lahn <> wrote:
    >> David Mark wrote:
    >>> On Dec 8, 9:33 am, Thomas 'PointedEars' Lahn <>
    >>> wrote:
    >>>> David Mark wrote:
    >>>>> I see the "When is a function not a function" thread has flared
    >>>>> up again. This is what I use to test parameters that can be
    >>>>> Functions or Objects. It does return the expected result for
    >>>>> callable host objects (at least the ones I tested.) None of the
    >>>>> functions it supports are expected to receive those as
    >>>>> parameters. The second part of the test is a little ambiguous in
    >>>>> this regard (for browsers that do not support call), so it is
    >>>>> best to exclude callable host objects as a rule. var isFunction =
    >>>>> function(o) { return typeof(o) == 'function' &&
    >>>>> (!Function.prototype.call || typeof(o.call) == 'function'); };
    >>>> isFunction() will return `false' where Function.prototype.call is
    >>>> not supported and the object has no `call' property, even though
    >>>> the argument referred to a Function object. That is the case in
    >>>> JavaScript before
    >>> If it is a Function then the first part of the conjunction is true.
    >>> The second part will also be true as !Function.prototype.call will
    >>> evaluate to true when call is not supported. So just what are you
    >>> talking about?

    >> Sorry, I have confused matters here. However, I would like to point
    >> out that it does not make sense to test against
    >> Function.prototype.call, be it in the negative direct or the positive
    >> indirect way. That the object has a(n *external*) `call' property has
    >> nothing to do with whether or not it is callable (with an argument
    >> list), having an *internal* [[Call]] method.

    >
    > It is not meant to return true for anything but Functions. It is not an
    > isCallable function.


    Again, if I already knew that the argument is a reference to a Function
    object, I would not need (to call) your method. Because Function objects
    are callable by default, and there is nothing, besides intentionally
    crippling the script engine by modifying its source code, that can change that.

    >>>> The argument may be an unqualified reference in which case calling
    >>>> this testing method fails if the identifier of that reference was
    >>>> not defined before.
    >>> You aren't allowed to pass anything but Function objects or Object
    >>> objects. Those are the rules as documented.

    >> That is ridiculous. One does not need to call the method if one
    >> already knows that the argument is a reference to a Function or Object
    >> object.

    >
    > As explained, it is for functions to test parameters, which may be
    > Function objects or Object objects. The functions that call it need to
    > distinguish between the two. It is not for feature detection, but for
    > overloading functions (typically those that perform callbacks.)


    I don't know what you mean by "overloading functions", but you delude
    yourself here if you think that the function in its current form can
    provide something that conventional programming cannot provide.

    > As I mentioned in the first post, but left out in the second, it also can
    > handle host objects (including those that are callable.)


    Not at all. The `typeof' operation on those objects could yield "object"
    and isFunction() would yield `false' then.

    >>> Results are not defined for anything else.

    >> Apparently you don't know what an unqualified reference is.

    >
    > I misread what you said. Of course I know what an unqualified reference
    > is. Didn't we just have a long discussion about them in a recent thread
    > (yesterday.)


    Yes, we had, and you did not demonstrate to understand the consequences of
    their use then, too.

    > Regardless, the function does exactly what it is designed to do.
    > Furthermore, this is not the first time it has been posted here. Go back
    > and read the original thread (which I started) and perhaps you will
    > understand the context of this one.
    >
    > As for unqualified references:
    >
    > isFunction(document) == false


    Maybe you know what an unqualified reference is, but you don't know what
    using them entails. If `document' was not defined (which is different
    from it having the `undefined' value), i.e. could not be resolved as
    per ES3 Final, subsections 8.7.1 and 10.1.4, the above will result in
    a ReferenceError, before isFunction() could be called.

    Now it is easy to respond to this then by stating that there is probably no
    HTML user agent that does not support `document'. But remember that this is
    but an example. In real code, let `document' be `foo' instead. The method
    should be able to determine whether or not `foo' referred to a method even
    though `foo' was not declared in the current execution context. Yet that
    is where it fails.

    > isFunction(attachEvent) == false // IE only of course, errors elsewhere


    Same here.

    > Do you see what I am testing for now?


    You are requiring the caller to provide a qualified reference which is not
    always possible and would otherwise not be necessary.

    > Methods of host objects do not apply,


    The identifier does not have to be a supposed reference to a method of a
    host object for this to fail.

    > despite the fact that they are obviously callable. Unqualified
    > references to methods of host objects do not return anything different
    > than qualified ones.


    Wrong, they may not return *anything* as there can not be a return value
    of the method if they could not be resolved and the method was never called.

    > So your point eludes me.


    That much is obvious.

    >>>> `typeof' is an operator, not a method, and should be written
    >>>> accordingly.
    >>> That is just my personal style. I've always written it that way and
    >>> I think it is easier to read.

    >> If it is also part of your personal style to have method identifiers
    >> followed by the argument list without whitespace, then there is a
    >> contradiction in it.

    >
    > An ambiguity, but not a contradiction.


    It is a contradiction to your statement that this would be easier to read.
    How can it be easier to read if it is not possible to differentiate at a
    glance between operators and methods?


    PointedEars
    --
    var bugRiddenCrashPronePieceOfJunk = (
    navigator.userAgent.indexOf('MSIE 5') != -1
    && navigator.userAgent.indexOf('Mac') != -1
    ) // Plone, register_function.js:16
     
    Thomas 'PointedEars' Lahn, Dec 8, 2007
    #6
  7. David Mark

    David Mark Guest

    On Dec 8, 12:22 pm, Thomas 'PointedEars' Lahn <>
    wrote:
    > David Mark wrote:
    > > On Dec 8, 11:07 am, Thomas 'PointedEars' Lahn <> wrote:
    > >> David Mark wrote:
    > >>> On Dec 8, 9:33 am, Thomas 'PointedEars' Lahn <>
    > >>> wrote:
    > >>>> David Mark wrote:
    > >>>>> I see the "When is a function not a function" thread has flared
    > >>>>> up again. This is what I use to test parameters that can be
    > >>>>> Functions or Objects. It does return the expected result for
    > >>>>> callable host objects (at least the ones I tested.) None of the
    > >>>>> functions it supports are expected to receive those as
    > >>>>> parameters. The second part of the test is a little ambiguous in
    > >>>>> this regard (for browsers that do not support call), so it is
    > >>>>> best to exclude callable host objects as a rule. var isFunction =
    > >>>>> function(o) { return typeof(o) == 'function' &&
    > >>>>> (!Function.prototype.call || typeof(o.call) == 'function'); };
    > >>>> isFunction() will return `false' where Function.prototype.call is
    > >>>> not supported and the object has no `call' property, even though
    > >>>> the argument referred to a Function object. That is the case in
    > >>>> JavaScript before
    > >>> If it is a Function then the first part of the conjunction is true.
    > >>> The second part will also be true as !Function.prototype.call will
    > >>> evaluate to true when call is not supported. So just what are you
    > >>> talking about?
    > >> Sorry, I have confused matters here. However, I would like to point
    > >> out that it does not make sense to test against
    > >> Function.prototype.call, be it in the negative direct or the positive
    > >> indirect way. That the object has a(n *external*) `call' property has
    > >> nothing to do with whether or not it is callable (with an argument
    > >> list), having an *internal* [[Call]] method.

    >
    > > It is not meant to return true for anything but Functions. It is not an
    > > isCallable function.

    >
    > Again, if I already knew that the argument is a reference to a Function
    > object, I would not need (to call) your method. Because Function objects


    You apparently haven't been paying attention. Let me try to simplify
    this for you. This function for my purposes could be as simple as:

    typeof(o) == 'function'

    The calling functions do NOT know whether their argument(s) are
    Functions or some other type of object. When they ARE DETERMINED TO
    BE FUNCTIONS by this test, they are called. When not, a method of the
    object is called. It was created specifically for callbacks as I
    already mentioned. How you translate that into "I already knew the
    argument is a reference to a Function object" after this has been
    explained three times already is beyond me.

    If you go back and read the original thread, you will understand why
    the additional logic was added (to weed out callable host objects and
    methods.) It is more of an academic exercise than anything and after
    thinking about it, I don't think it needs to be in the repository.

    [snip]

    >
    > I don't know what you mean by "overloading functions", but you delude


    Of course you do. You are simply being deliberately obtuse. Having a
    bad day today?

    > yourself here if you think that the function in its current form can
    > provide something that conventional programming cannot provide.


    Define "conventional programming."

    >
    > > As I mentioned in the first post, but left out in the second, it also can
    > > handle host objects (including those that are callable.)

    >
    > Not at all. The `typeof' operation on those objects could yield "object"
    > and isFunction() would yield `false' then.


    Once again. You are not paying attention. Please go back and re-read
    the original thread. False is what I want this to return for callable
    host objects and their methods. Those are not Functions.

    >
    > >>> Results are not defined for anything else.
    > >> Apparently you don't know what an unqualified reference is.

    >
    > > I misread what you said. Of course I know what an unqualified reference
    > > is. Didn't we just have a long discussion about them in a recent thread
    > > (yesterday.)

    >
    > Yes, we had, and you did not demonstrate to understand the consequences of
    > their use then, too.


    Wrong. You can't seem to keep track of your own arguments. Your
    whole point in that other thread was that you were sure that the
    window object didn't refer to the global object in some HTML UA that
    you can't name.

    >
    > > Regardless, the function does exactly what it is designed to do.
    > > Furthermore, this is not the first time it has been posted here. Go back
    > > and read the original thread (which I started) and perhaps you will
    > > understand the context of this one.

    >
    > > As for unqualified references:

    >
    > > isFunction(document) == false

    >
    > Maybe you know what an unqualified reference is, but you don't know what
    > using them entails. If `document' was not defined (which is different


    Whatever that means.

    > from it having the `undefined' value), i.e. could not be resolved as
    > per ES3 Final, subsections 8.7.1 and 10.1.4, the above will result in
    > a ReferenceError, before isFunction() could be called.


    Thanks professor.

    >
    > Now it is easy to respond to this then by stating that there is probably no
    > HTML user agent that does not support `document'. But remember that this is


    Probably not.

    > but an example. In real code, let `document' be `foo' instead. The method
    > should be able to determine whether or not `foo' referred to a method even
    > though `foo' was not declared in the current execution context. Yet that
    > is where it fails.


    You are just babbling nonsense. The function get a copy of a
    reference to some object, which it tests with typeof and returns an
    appropriate result.

    [snip more of the same nonsense]

    >
    > > despite the fact that they are obviously callable. Unqualified
    > > references to methods of host objects do not return anything different
    > > than qualified ones.

    >
    > Wrong, they may not return *anything* as there can not be a return value
    > of the method if they could not be resolved and the method was never called.


    Thanks again, professor. I do realize that
    isFunction(someundeclaredidentifier) will error.

    >
    > > So your point eludes me.

    >
    > That much is obvious.


    Your aggregated point(s) have eluded most of this group (and
    reportedly others) for some time. Have you noticed this pattern?

    >
    > >>>> `typeof' is an operator, not a method, and should be written
    > >>>> accordingly.
    > >>> That is just my personal style. I've always written it that way and
    > >>> I think it is easier to read.
    > >> If it is also part of your personal style to have method identifiers
    > >> followed by the argument list without whitespace, then there is a
    > >> contradiction in it.

    >
    > > An ambiguity, but not a contradiction.

    >
    > It is a contradiction to your statement that this would be easier to read.
    > How can it be easier to read if it is not possible to differentiate at a
    > glance between operators and methods?


    Because one of them has "typeof" before the opening parenthesis? I
    know that typeof is not a function, so it would be impossible to
    mistake at for one.
     
    David Mark, Dec 8, 2007
    #7
  8. David Mark wrote:
    > On Dec 8, 12:22 pm, Thomas 'PointedEars' Lahn <>
    > wrote:
    >> David Mark wrote:
    >>> On Dec 8, 11:07 am, Thomas 'PointedEars' Lahn <> wrote:
    >>>> David Mark wrote:
    >>>>> On Dec 8, 9:33 am, Thomas 'PointedEars' Lahn <>
    >>>>> wrote:
    >>>>>> David Mark wrote:
    >>>>>>> I see the "When is a function not a function" thread has flared
    >>>>>>> up again. This is what I use to test parameters that can be
    >>>>>>> Functions or Objects. It does return the expected result for
    >>>>>>> callable host objects (at least the ones I tested.) None of the
    >>>>>>> functions it supports are expected to receive those as
    >>>>>>> parameters. The second part of the test is a little ambiguous in
    >>>>>>> this regard (for browsers that do not support call), so it is
    >>>>>>> best to exclude callable host objects as a rule. var isFunction =
    >>>>>>> function(o) { return typeof(o) == 'function' &&
    >>>>>>> (!Function.prototype.call || typeof(o.call) == 'function'); };
    >>>>>> isFunction() will return `false' where Function.prototype.call is
    >>>>>> not supported and the object has no `call' property, even though
    >>>>>> the argument referred to a Function object. That is the case in
    >>>>>> JavaScript before
    >>>>> If it is a Function then the first part of the conjunction is true.
    >>>>> The second part will also be true as !Function.prototype.call will
    >>>>> evaluate to true when call is not supported. So just what are you
    >>>>> talking about?
    >>>> Sorry, I have confused matters here. However, I would like to point
    >>>> out that it does not make sense to test against
    >>>> Function.prototype.call, be it in the negative direct or the positive
    >>>> indirect way. That the object has a(n *external*) `call' property has
    >>>> nothing to do with whether or not it is callable (with an argument
    >>>> list), having an *internal* [[Call]] method.
    >>> It is not meant to return true for anything but Functions. It is not an
    >>> isCallable function.

    >> Again, if I already knew that the argument is a reference to a Function
    >> object, I would not need (to call) your method. Because Function objects

    >
    > You apparently haven't been paying attention.


    It is certain now that you don't know what you are doing.

    > Let me try to simplify this for you. This function for my purposes
    > could be as simple as:
    >
    > typeof(o) == 'function'


    Exactly my point. You don't need a function to test that at all. A
    function that will also have the drawback, as compared to the already
    available alternative, of requiring the caller to provide a qualified reference.

    >> yourself here if you think that the function in its current form can
    >> provide something that conventional programming cannot provide.

    >
    > Define "conventional programming."


    A simple `typeof' operation that is not needlessly wrapped in a test method.

    >>> As I mentioned in the first post, but left out in the second, it also can
    >>> handle host objects (including those that are callable.)

    >> Not at all. The `typeof' operation on those objects could yield "object"
    >> and isFunction() would yield `false' then.

    >
    > Once again. You are not paying attention. Please go back and re-read
    > the original thread. False is what I want this to return for callable
    > host objects and their methods. Those are not Functions.


    You are the one who has not been paying attention. You have stated that
    isFunction() "can handle host objects (including those that are callable)"
    and I have explained that and why that is wrong.

    >>> Regardless, the function does exactly what it is designed to do.
    >>> Furthermore, this is not the first time it has been posted here. Go back
    >>> and read the original thread (which I started) and perhaps you will
    >>> understand the context of this one.
    >>> As for unqualified references:
    >>> isFunction(document) == false

    >> Maybe you know what an unqualified reference is, but you don't know what
    >> using them entails. If `document' was not defined (which is different

    >
    > Whatever that means.
    >
    >> from it having the `undefined' value), i.e. could not be resolved as
    >> per ES3 Final, subsections 8.7.1 and 10.1.4, the above will result in
    >> a ReferenceError, before isFunction() could be called.

    >
    > Thanks professor.
    >
    >> but an example. In real code, let `document' be `foo' instead. The method
    >> should be able to determine whether or not `foo' referred to a method even
    >> though `foo' was not declared in the current execution context. Yet that
    >> is where it fails.

    >
    > You are just babbling nonsense. The function get a copy of a
    > reference to some object, which it tests with typeof and returns an
    > appropriate result.


    You fool, call e.g. isFunction(encodeURIComponent) in IE 5.01 or apply
    isMethod() to any other unqualified reference to an unsupported method
    of the Global Object or any other native object in the scope chain, and
    see it failing right before your eyes, before any test can take place,
    where

    typeof encodeURIComponent == "function"

    would never fail and would always yield a result (since JavaScript 1.1,
    JScript 1.0, ECMAScript 1).

    >>> despite the fact that they are obviously callable. Unqualified
    >>> references to methods of host objects do not return anything different
    >>> than qualified ones.

    >> Wrong, they may not return *anything* as there can not be a return value
    >> of the method if they could not be resolved and the method was never called.

    >
    > Thanks again, professor. I do realize that
    > isFunction(someundeclaredidentifier) will error.


    No, you don't.

    >>> So your point eludes me.

    >> That much is obvious.

    >
    > Your aggregated point(s) have eluded most of this group (and
    > reportedly others) for some time. Have you noticed this pattern?


    Now you already argue with the silent majority. Are you really that finished?

    >>>>>> `typeof' is an operator, not a method, and should be written
    >>>>>> accordingly.
    >>>>> That is just my personal style. I've always written it that way and
    >>>>> I think it is easier to read.
    >>>> If it is also part of your personal style to have method identifiers
    >>>> followed by the argument list without whitespace, then there is a
    >>>> contradiction in it.
    >>> An ambiguity, but not a contradiction.

    >> It is a contradiction to your statement that this would be easier to read.
    >> How can it be easier to read if it is not possible to differentiate at a
    >> glance between operators and methods?

    >
    > Because one of them has "typeof" before the opening parenthesis? I
    > know that typeof is not a function, so it would be impossible to
    > mistake at for one.


    Yet the contradiction in your argumentation remains.


    PointedEars
     
    Thomas 'PointedEars' Lahn, Dec 8, 2007
    #8
  9. David Mark

    David Mark Guest

    On Dec 8, 2:30 pm, Thomas 'PointedEars' Lahn <>
    wrote:
    > David Mark wrote:
    > > On Dec 8, 12:22 pm, Thomas 'PointedEars' Lahn <>
    > > wrote:
    > >> David Mark wrote:
    > >>> On Dec 8, 11:07 am, Thomas 'PointedEars' Lahn <> wrote:
    > >>>> David Mark wrote:
    > >>>>> On Dec 8, 9:33 am, Thomas 'PointedEars' Lahn <>
    > >>>>> wrote:
    > >>>>>> David Mark wrote:
    > >>>>>>> I see the "When is a function not a function" thread has flared
    > >>>>>>> up again. This is what I use to test parameters that can be
    > >>>>>>> Functions or Objects. It does return the expected result for
    > >>>>>>> callable host objects (at least the ones I tested.) None of the
    > >>>>>>> functions it supports are expected to receive those as
    > >>>>>>> parameters. The second part of the test is a little ambiguous in
    > >>>>>>> this regard (for browsers that do not support call), so it is
    > >>>>>>> best to exclude callable host objects as a rule. var isFunction =
    > >>>>>>> function(o) { return typeof(o) == 'function' &&
    > >>>>>>> (!Function.prototype.call || typeof(o.call) == 'function'); };
    > >>>>>> isFunction() will return `false' where Function.prototype.call is
    > >>>>>> not supported and the object has no `call' property, even though
    > >>>>>> the argument referred to a Function object. That is the case in
    > >>>>>> JavaScript before
    > >>>>> If it is a Function then the first part of the conjunction is true.
    > >>>>> The second part will also be true as !Function.prototype.call will
    > >>>>> evaluate to true when call is not supported. So just what are you
    > >>>>> talking about?
    > >>>> Sorry, I have confused matters here. However, I would like to point
    > >>>> out that it does not make sense to test against
    > >>>> Function.prototype.call, be it in the negative direct or the positive
    > >>>> indirect way. That the object has a(n *external*) `call' property has
    > >>>> nothing to do with whether or not it is callable (with an argument
    > >>>> list), having an *internal* [[Call]] method.
    > >>> It is not meant to return true for anything but Functions. It is not an
    > >>> isCallable function.
    > >> Again, if I already knew that the argument is a reference to a Function
    > >> object, I would not need (to call) your method. Because Function objects

    >
    > > You apparently haven't been paying attention.

    >
    > It is certain now that you don't know what you are doing.


    Or perhaps you don't know how to read.

    >
    > > Let me try to simplify this for you. This function for my purposes
    > > could be as simple as:

    >
    > > typeof(o) == 'function'

    >
    > Exactly my point. You don't need a function to test that at all. A
    > function that will also have the drawback, as compared to the already
    > available alternative, of requiring the caller to provide a qualified reference.


    That's not the point. I wouldn't use a function that only did that.
    We've already had this conversation with regard to the feature testing
    wrappers (yesterday.) I did update those and gave you credit for a
    rare insight. What you fail to realize is that this function is a
    different animal.

    >
    > >> yourself here if you think that the function in its current form can
    > >> provide something that conventional programming cannot provide.

    >
    > > Define "conventional programming."

    >
    > A simple `typeof' operation that is not needlessly wrapped in a test method.


    You really need to go back and read the original thread that this
    relates to. A simple typeof is not sufficient to solve the original
    problem presented.

    >
    > >>> As I mentioned in the first post, but left out in the second, it also can
    > >>> handle host objects (including those that are callable.)
    > >> Not at all. The `typeof' operation on those objects could yield "object"
    > >> and isFunction() would yield `false' then.

    >
    > > Once again. You are not paying attention. Please go back and re-read
    > > the original thread. False is what I want this to return for callable
    > > host objects and their methods. Those are not Functions.

    >
    > You are the one who has not been paying attention. You have stated that
    > isFunction() "can handle host objects (including those that are callable)"
    > and I have explained that and why that is wrong.


    No you fail to understand that I defined what is right or wrong for
    this function, tested it and verified that the results are exactly
    what I expected them to be. Your concept of what this function is
    supposed to do is apparently different from mine.

    >
    >
    >
    >
    >
    > >>> Regardless, the function does exactly what it is designed to do.
    > >>> Furthermore, this is not the first time it has been posted here. Go back
    > >>> and read the original thread (which I started) and perhaps you will
    > >>> understand the context of this one.
    > >>> As for unqualified references:
    > >>> isFunction(document) == false
    > >> Maybe you know what an unqualified reference is, but you don't know what
    > >> using them entails. If `document' was not defined (which is different

    >
    > > Whatever that means.

    >
    > >> from it having the `undefined' value), i.e. could not be resolved as
    > >> per ES3 Final, subsections 8.7.1 and 10.1.4, the above will result in
    > >> a ReferenceError, before isFunction() could be called.

    >
    > > Thanks professor.

    >
    > >> but an example. In real code, let `document' be `foo' instead. The method
    > >> should be able to determine whether or not `foo' referred to a method even
    > >> though `foo' was not declared in the current execution context. Yet that
    > >> is where it fails.

    >
    > > You are just babbling nonsense. The function get a copy of a
    > > reference to some object, which it tests with typeof and returns an
    > > appropriate result.

    >
    > You fool, call e.g. isFunction(encodeURIComponent) in IE 5.01 or apply


    Dummkopf. We've been over that. You are talking in circles.

    > isMethod() to any other unqualified reference to an unsupported method


    isMethod? What's that?

    [snip tiresome repetition]

    >
    > >>> despite the fact that they are obviously callable. Unqualified
    > >>> references to methods of host objects do not return anything different
    > >>> than qualified ones.
    > >> Wrong, they may not return *anything* as there can not be a return value
    > >> of the method if they could not be resolved and the method was never called.

    >
    > > Thanks again, professor. I do realize that
    > > isFunction(someundeclaredidentifier) will error.

    >
    > No, you don't.


    Then why did I write it?

    >
    > >>> So your point eludes me.
    > >> That much is obvious.

    >
    > > Your aggregated point(s) have eluded most of this group (and
    > > reportedly others) for some time. Have you noticed this pattern?

    >
    > Now you already argue with the silent majority. Are you really that finished?


    I can't make heads or tails of that. But the majority I speak of has
    baen anything but silent about the quality (or lack thereof) of your
    posts. In fact, it has been suggested repeatedly that you are
    completely crackers.
     
    David Mark, Dec 8, 2007
    #9
  10. On Dec 8, 11:05 am, David Mark <> wrote:
    > On Dec 8, 12:22 pm, Thomas 'PointedEars' Lahn <>
    > wrote:
    >
    >
    >
    > > David Mark wrote:
    > > > On Dec 8, 11:07 am, Thomas 'PointedEars' Lahn <> wrote:
    > > >> David Mark wrote:
    > > >>> On Dec 8, 9:33 am, Thomas 'PointedEars' Lahn <>
    > > >>> wrote:
    > > >>>> David Mark wrote:
    > > >>>>> I see the "When is a function not a function" thread has flared
    > > >>>>> up again. This is what I use to test parameters that can be
    > > >>>>> Functions or Objects. It does return the expected result for
    > > >>>>> callable host objects (at least the ones I tested.) None of the
    > > >>>>> functions it supports are expected to receive those as
    > > >>>>> parameters. The second part of the test is a little ambiguous in
    > > >>>>> this regard (for browsers that do not support call), so it is
    > > >>>>> best to exclude callable host objects as a rule. var isFunction =
    > > >>>>> function(o) { return typeof(o) == 'function' &&
    > > >>>>> (!Function.prototype.call || typeof(o.call) == 'function'); };
    > > >>>> isFunction() will return `false' where Function.prototype.call is
    > > >>>> not supported and the object has no `call' property, even though
    > > >>>> the argument referred to a Function object. That is the case in
    > > >>>> JavaScript before
    > > >>> If it is a Function then the first part of the conjunction is true.
    > > >>> The second part will also be true as !Function.prototype.call will
    > > >>> evaluate to true when call is not supported. So just what are you
    > > >>> talking about?
    > > >> Sorry, I have confused matters here. However, I would like to point
    > > >> out that it does not make sense to test against
    > > >> Function.prototype.call, be it in the negative direct or the positive
    > > >> indirect way. That the object has a(n *external*) `call' property has
    > > >> nothing to do with whether or not it is callable (with an argument
    > > >> list), having an *internal* [[Call]] method.

    >
    > > > It is not meant to return true for anything but Functions. It is not an
    > > > isCallable function.

    >
    > > Again, if I already knew that the argument is a reference to a Function
    > > object, I would not need (to call) your method. Because Function objects

    >
    > You apparently haven't been paying attention. Let me try to simplify
    > this for you. This function for my purposes could be as simple as:
    >
    > typeof(o) == 'function'
    >
    > The calling functions do NOT know whether their argument(s) are
    > Functions or some other type of object. When they ARE DETERMINED TO
    > BE FUNCTIONS by this test, they are called. When not, a method of the
    > object is called. It was created specifically for callbacks as I
    > already mentioned. How you translate that into "I already knew the
    > argument is a reference to a Function object" after this has been
    > explained three times already is beyond me.
    >
    > If you go back and read the original thread, you will understand why
    > the additional logic was added (to weed out callable host objects and
    > methods.)


    I know a callable host object may not be a "function" but if I was
    using a function called "isFunction" I'd expect that if I send it any
    callable object it would return true.

    > It is more of an academic exercise than anything and after
    > thinking about it, I don't think it needs to be in the repository.


    I agree (at least for now). I think the repository should gain
    foundational functions like this as needed for bigger pieces of code
    (e.g. Ajax, events, etc). I've never created an overloaded JavaScript
    function where the overloaded argument could be a function or not. As
    far as I know, I've only ever had an overloaded argument for an
    element or an element id string. Because of this I haven't really
    followed along with the various "when is a function not a function"
    threads.

    [snip]

    --
    Peter
    Code Worth Recommending Project
    http://cljs.michaux.ca
     
    Peter Michaux, Dec 9, 2007
    #10
  11. David Mark

    RobG Guest

    Peter Michaux wrote:
    > On Dec 8, 11:05 am, David Mark <> wrote:
    >> On Dec 8, 12:22 pm, Thomas 'PointedEars' Lahn <>
    >> wrote:
    >>
    >>
    >>
    >>> David Mark wrote:
    >>>> On Dec 8, 11:07 am, Thomas 'PointedEars' Lahn <> wrote:

    [...]
    >>>>> Sorry, I have confused matters here. However, I would like to point
    >>>>> out that it does not make sense to test against
    >>>>> Function.prototype.call, be it in the negative direct or the positive
    >>>>> indirect way. That the object has a(n *external*) `call' property has
    >>>>> nothing to do with whether or not it is callable (with an argument
    >>>>> list), having an *internal* [[Call]] method.
    >>>> It is not meant to return true for anything but Functions. It is not an
    >>>> isCallable function.


    I would expect that the primary purpose of an isFunction function would
    be to see if something is callable. I can't imagine a practical
    scenario where I'd want to know if something is a function without
    wanting to know whether it's callable.

    Given that the proposed function returns false for host objects in IE,
    and true for the same objects in (all?) other browsers, it doesn't seem
    worth recommending.

    Since it seems that the focus should be on whether something is callable
    and not whether or not it is, strictly, a Function, then I'd suggest
    that isCallable is what is required, not isFunction.

    >>> Again, if I already knew that the argument is a reference to a Function
    >>> object, I would not need (to call) your method. Because Function objects

    >> You apparently haven't been paying attention. Let me try to simplify
    >> this for you. This function for my purposes could be as simple as:
    >>
    >> typeof(o) == 'function'


    If you are prepared to accept that isFunction(document.getElementById)
    returns false even if it is a function and callable.


    >> The calling functions do NOT know whether their argument(s) are
    >> Functions or some other type of object. When they ARE DETERMINED TO
    >> BE FUNCTIONS by this test, they are called.


    So it is being used as if it were isCallable.

    >> When not, a method of the
    >> object is called. It was created specifically for callbacks as I
    >> already mentioned. How you translate that into "I already knew the
    >> argument is a reference to a Function object" after this has been
    >> explained three times already is beyond me.
    >>
    >> If you go back and read the original thread, you will understand why
    >> the additional logic was added (to weed out callable host objects and
    >> methods.)

    >
    > I know a callable host object may not be a "function" but if I was
    > using a function called "isFunction" I'd expect that if I send it any
    > callable object it would return true.


    Either that or there was a prominently placed isCallable function that
    also pointed out the difference between the two, something like:

    "isFunction returns true if an object is a function, but does
    not guarantee that it can be called."

    "To test if an object is callable, use isCallable. It returns
    true if an object is callable, regardless of whether it is a
    function or not."


    >
    >> It is more of an academic exercise than anything and after
    >> thinking about it, I don't think it needs to be in the repository.

    >
    > I agree (at least for now). I think the repository should gain
    > foundational functions like this as needed for bigger pieces of code
    > (e.g. Ajax, events, etc).


    There seems to be agreement that determining whether an object is a
    function is not a reliable indicator of whether it may be called, and
    that there is a general need to determine whether or not something is
    callable. Therefore, there is a need for an isCallable function.

    Such a function could be used for feature testing host functions and
    also native functions where appropriate.

    In an ECMAScript ed3 compliant implementation, typeof should reliably
    indicate whether something is callable (since the very definition of
    when typeof obj returns 'function' is that the object implements
    [[call]]) then all that needs to be dealt with are edge cases, i.e. IE.

    I think it is a mistake to look for public properties called 'call', as
    that may not indicate that it is a method. Such a function could be
    based on:

    var isCallable = (function(){
    if (typeof document.getElementById == 'function') {
    return function(o) {
    return typeof o == 'function';
    }
    }
    if (typeof document.getElementById == 'object') {
    return function(o){
    // What test works in IE for host functions?
    // The following seems too loose:
    return typeof o == 'function'
    || typeof o == 'object';
    }
    }
    })();

    However clearly there is a need for a better test for IE host functions.


    --
    Rob
    "We shall not cease from exploration, and the end of all our
    exploring will be to arrive where we started and know the
    place for the first time." -- T. S. Eliot
     
    RobG, Dec 9, 2007
    #11
  12. On Dec 8, 10:32 pm, RobG <> wrote:
    > Peter Michaux wrote:
    > > On Dec 8, 11:05 am, David Mark <> wrote:
    > > >
    > > > It is more of an academic exercise than anything and after
    > > > thinking about it, I don't think it needs to be in the
    > > > repository.

    >
    > > I agree (at least for now). I think the repository should gain
    > > foundational functions like this as needed for bigger pieces of
    > > code (e.g. Ajax, events, etc).

    >
    > There seems to be agreement that determining whether an object is a
    > function is not a reliable indicator of whether it may be called, and
    > that there is a general need to determine whether or not something is
    > callable. Therefore, there is a need for an isCallable function.


    It seems like such a function is at least difficult to write and
    people have been getting by without it. It is certainly possible to
    write all the basic parts of a browser scripting library without such
    a function. If there is a general interest in having such a function
    in the repository and such a function can be written to perform
    reliably then it should be added to the repository.

    --
    Peter
    Code Worth Recommending Project
    http://cljs.michaux.ca
     
    Peter Michaux, Dec 9, 2007
    #12
  13. David Mark

    RobG Guest

    Peter Michaux wrote:
    > On Dec 8, 10:32 pm, RobG <> wrote:
    >> Peter Michaux wrote:
    >>> On Dec 8, 11:05 am, David Mark <> wrote:
    >>>> It is more of an academic exercise than anything and after
    >>>> thinking about it, I don't think it needs to be in the
    >>>> repository.
    >>> I agree (at least for now). I think the repository should gain
    >>> foundational functions like this as needed for bigger pieces of
    >>> code (e.g. Ajax, events, etc).

    >> There seems to be agreement that determining whether an object is a
    >> function is not a reliable indicator of whether it may be called, and
    >> that there is a general need to determine whether or not something is
    >> callable. Therefore, there is a need for an isCallable function.

    >
    > It seems like such a function is at least difficult to write and
    > people have been getting by without it. It is certainly possible to
    > write all the basic parts of a browser scripting library without such
    > a function. If there is a general interest in having such a function
    > in the repository and such a function can be written to perform
    > reliably then it should be added to the repository.


    Yes, and at the end of this exploration we are back to:


    1. For host methods (aka feature detection), use:

    if (hostObj && hostObj.method) {
    hostObj.method();
    }


    2. If you know fn isn't a host method but should be
    a native function, use:

    if (typeof fn == 'function') {
    fn();
    }

    3. If you don't know (and these cases should be kept
    to a minimum), use:

    if (typeof obj == 'function' || typeof obj == 'object') {
    obj();
    }


    where the term "function" used above means a native object that
    implements [[call]].


    P.S. I agree with Thomas about not using brackets with typeof. :)


    --
    Rob
    "We shall not cease from exploration, and the end of all our
    exploring will be to arrive where we started and know the
    place for the first time." -- T. S. Eliot
     
    RobG, Dec 9, 2007
    #13
  14. David Mark

    David Mark Guest

    On Dec 9, 1:32 am, RobG <> wrote:
    > Peter Michaux wrote:
    > > On Dec 8, 11:05 am, David Mark <> wrote:
    > >> On Dec 8, 12:22 pm, Thomas 'PointedEars' Lahn <>
    > >> wrote:

    >
    > >>> David Mark wrote:
    > >>>> On Dec 8, 11:07 am, Thomas 'PointedEars' Lahn <> wrote:

    > [...]
    > >>>>> Sorry, I have confused matters here. However, I would like to point
    > >>>>> out that it does not make sense to test against
    > >>>>> Function.prototype.call, be it in the negative direct or the positive
    > >>>>> indirect way. That the object has a(n *external*) `call' property has
    > >>>>> nothing to do with whether or not it is callable (with an argument
    > >>>>> list), having an *internal* [[Call]] method.
    > >>>> It is not meant to return true for anything but Functions. It is not an
    > >>>> isCallable function.

    >
    > I would expect that the primary purpose of an isFunction function would
    > be to see if something is callable. I can't imagine a practical


    Not in this case, though it isn't necessarily a practical case.

    > scenario where I'd want to know if something is a function without
    > wanting to know whether it's callable.


    A callback passed to a function that could either be a function or an
    object is what prompted the original thread on this. Specifically, if
    an object (usually an Object object) is passed, then a predefined
    method is called on it. Further discussion ensued concerning the fact
    that host objects could be mistaken for functions. It was determined
    that testing for the call method excluded those from consideration, so
    instead of failing silently by calling them as callbacks, an error
    would rightfully occur as they would be treated as objects and the
    predefined method name would not exist.

    >
    > Given that the proposed function returns false for host objects in IE,
    > and true for the same objects in (all?) other browsers, it doesn't seem
    > worth recommending.


    AFAIK, that isn't the case. It only returns true for Functions. For
    example, document.images is callable in some browsers, but will not
    return true with this function.

    >
    > Since it seems that the focus should be on whether something is callable
    > and not whether or not it is, strictly, a Function, then I'd suggest
    > that isCallable is what is required, not isFunction.


    That is an issue for another (more practical) function.

    >
    > >>> Again, if I already knew that the argument is a reference to a Function
    > >>> object, I would not need (to call) your method. Because Function objects
    > >> You apparently haven't been paying attention. Let me try to simplify
    > >> this for you. This function for my purposes could be as simple as:

    >
    > >> typeof(o) == 'function'

    >
    > If you are prepared to accept that isFunction(document.getElementById)
    > returns false even if it is a function and callable.


    That would be appropriate for what this function was designed to
    demonstrate.

    >
    > >> The calling functions do NOT know whether their argument(s) are
    > >> Functions or some other type of object. When they ARE DETERMINED TO
    > >> BE FUNCTIONS by this test, they are called.

    >
    > So it is being used as if it were isCallable.


    No. The document.images property in Safari is callable, but is not a
    Function. Same for document.getElementById in every browser. Those
    return false as passing them as callbacks to the functions that rely
    on this test is seen as a mistake.

    >
    > >> When not, a method of the
    > >> object is called. It was created specifically for callbacks as I
    > >> already mentioned. How you translate that into "I already knew the
    > >> argument is a reference to a Function object" after this has been
    > >> explained three times already is beyond me.

    >
    > >> If you go back and read the original thread, you will understand why
    > >> the additional logic was added (to weed out callable host objects and
    > >> methods.)

    >
    > > I know a callable host object may not be a "function" but if I was
    > > using a function called "isFunction" I'd expect that if I send it any
    > > callable object it would return true.

    >
    > Either that or there was a prominently placed isCallable function that
    > also pointed out the difference between the two, something like:
    >
    > "isFunction returns true if an object is a function, but does
    > not guarantee that it can be called."


    What sort of function cannot be called?

    >
    > "To test if an object is callable, use isCallable. It returns
    > true if an object is callable, regardless of whether it is a
    > function or not."
    >
    >
    >
    > >> It is more of an academic exercise than anything and after
    > >> thinking about it, I don't think it needs to be in the repository.

    >
    > > I agree (at least for now). I think the repository should gain
    > > foundational functions like this as needed for bigger pieces of code
    > > (e.g. Ajax, events, etc).

    >
    > There seems to be agreement that determining whether an object is a
    > function is not a reliable indicator of whether it may be called, and


    I don't agree with that.

    > that there is a general need to determine whether or not something is
    > callable. Therefore, there is a need for an isCallable function.


    The best you can do for host objects is to test if typeof evaluates to
    "object" or "function" and that the value isn't null. This is no
    guarantee, but has been demonstrated to be reliable for feature
    testing (so far.) This is covered in the current thread concerning
    gEBI/gEBTN wrappers.

    >
    > Such a function could be used for feature testing host functions and
    > also native functions where appropriate.


    Host methods is what I use it for. I haven't found the need to test
    native functions.

    >
    > In an ECMAScript ed3 compliant implementation, typeof should reliably
    > indicate whether something is callable (since the very definition of
    > when typeof obj returns 'function' is that the object implements
    > [[call]]) then all that needs to be dealt with are edge cases, i.e. IE.


    Right.

    >
    > I think it is a mistake to look for public properties called 'call', as
    > that may not indicate that it is a method. Such a function could be


    That test weeds out callable host objects (e.g. document.images) and
    methods (e.g. document.getElementById.) That was why it was added in
    the first place. The original thread on this has more details.

    > based on:
    >
    > var isCallable = (function(){
    > if (typeof document.getElementById == 'function') {
    > return function(o) {
    > return typeof o == 'function';
    > }
    > }


    That seems like too broad an inference.

    > if (typeof document.getElementById == 'object') {
    > return function(o){
    > // What test works in IE for host functions?
    > // The following seems too loose:
    > return typeof o == 'function'
    > || typeof o == 'object';


    You should certainly check that o !== null. Other than that, there
    isn't anything else you can do. See the isFeaturedMethod function in
    the other thread.
     
    David Mark, Dec 9, 2007
    #14
  15. David Mark

    David Mark Guest

    On Dec 9, 1:52 am, Peter Michaux <> wrote:
    > On Dec 8, 10:32 pm, RobG <> wrote:
    >
    > > Peter Michaux wrote:
    > > > On Dec 8, 11:05 am, David Mark <> wrote:

    >
    > > > > It is more of an academic exercise than anything and after
    > > > > thinking about it, I don't think it needs to be in the
    > > > > repository.

    >
    > > > I agree (at least for now). I think the repository should gain
    > > > foundational functions like this as needed for bigger pieces of
    > > > code (e.g. Ajax, events, etc).

    >
    > > There seems to be agreement that determining whether an object is a
    > > function is not a reliable indicator of whether it may be called, and
    > > that there is a general need to determine whether or not something is
    > > callable. Therefore, there is a need for an isCallable function.

    >
    > It seems like such a function is at least difficult to write and
    > people have been getting by without it. It is certainly possible to
    > write all the basic parts of a browser scripting library without such
    > a function. If there is a general interest in having such a function
    > in the repository and such a function can be written to perform
    > reliably then it should be added to the repository.
    >


    The primary need for this is to feature test host methods. It is
    covered by isFeaturedMethod in the gEBI wrapper thread.
     
    David Mark, Dec 9, 2007
    #15
  16. David Mark

    David Mark Guest

    On Dec 9, 2:20 am, RobG <> wrote:
    > Peter Michaux wrote:
    > > On Dec 8, 10:32 pm, RobG <> wrote:
    > >> Peter Michaux wrote:
    > >>> On Dec 8, 11:05 am, David Mark <> wrote:
    > >>>> It is more of an academic exercise than anything and after
    > >>>> thinking about it, I don't think it needs to be in the
    > >>>> repository.
    > >>> I agree (at least for now). I think the repository should gain
    > >>> foundational functions like this as needed for bigger pieces of
    > >>> code (e.g. Ajax, events, etc).
    > >> There seems to be agreement that determining whether an object is a
    > >> function is not a reliable indicator of whether it may be called, and
    > >> that there is a general need to determine whether or not something is
    > >> callable. Therefore, there is a need for an isCallable function.

    >
    > > It seems like such a function is at least difficult to write and
    > > people have been getting by without it. It is certainly possible to
    > > write all the basic parts of a browser scripting library without such
    > > a function. If there is a general interest in having such a function
    > > in the repository and such a function can be written to perform
    > > reliably then it should be added to the repository.

    >
    > Yes, and at the end of this exploration we are back to:
    >
    > 1. For host methods (aka feature detection), use:
    >
    > if (hostObj && hostObj.method) {
    > hostObj.method();
    > }


    I consider that insufficient. For one, it will error on methods of
    ActiveX objects.

    >
    > 2. If you know fn isn't a host method but should be
    > a native function, use:
    >
    > if (typeof fn == 'function') {
    > fn();
    > }
    >
    > 3. If you don't know (and these cases should be kept
    > to a minimum), use:
    >
    > if (typeof obj == 'function' || typeof obj == 'object') {
    > obj();
    > }


    This is a partial solution to feature testing host methods. This is
    what I use:

    var reFeaturedMethod = new RegExp('^function|object$', 'i');

    var isFeaturedMethod = function(o, m) {
    var t = typeof(o[m]);
    return !!((reFeaturedMethod.test(t) && o[m]) || t == 'unknown');
    };

    That covers ActiveX methods and null objects. As Thomas pointed out
    (repeatedly), o must be a full qualified reference, which seems to be
    an issue for him, though I don't consider it a problem.
     
    David Mark, Dec 9, 2007
    #16
  17. RobG wrote:
    > 1. For host methods (aka feature detection), use:
    >
    > if (hostObj && hostObj.method) {
    > hostObj.method();
    > }


    I don't think so, and I have already explained why.

    > 2. If you know fn isn't a host method but should be
    > a native function, use:
    >
    > if (typeof fn == 'function') {
    > fn();
    > }
    >
    > 3. If you don't know (and these cases should be kept
    > to a minimum), use:
    >
    > if (typeof obj == 'function' || typeof obj == 'object') {
    > obj();
    > }


    Generally, ACK to those two. However, the very problem here is that
    you _never_ know. As I have said, we would not need feature detection
    if we already knew :)

    > where the term "function" used above means a native object that
    > implements [[call]].


    1. [[Call]]

    2. AIUI, it would not necessarily be *an implementation of* [[Call]],
    as
    host objects may perform calling in any way the implementor saw
    fit.

    > P.S. I agree with Thomas about not using brackets with typeof. :)


    Thanks. However, I did not suggest to avoid parentheses in a `typeof'
    operation altogether. There is nothing wrong with writing those; in
    fact, it may be necessary to force precedence. I suggested instead
    that the `typeof' keyword be followed by space so as to indicate it is
    an operator and not, as its being followed directly by a parenthesed
    expression would indicate, a method. (Of course, if parentheses are
    not used, that would require `typeof' to be followed by whitespace,
    else it would not be parsed as a keyword.)


    Regards,

    PointedEars
     
    Thomas 'PointedEars' Lahn, Dec 10, 2007
    #17
  18. David Mark

    David Mark Guest

    On Dec 10, 8:38 am, "Thomas 'PointedEars' Lahn" <>
    wrote:
    [snip]
    >
    > Thanks. However, I did not suggest to avoid parentheses in a `typeof'
    > operation altogether. There is nothing wrong with writing those; in
    > fact, it may be necessary to force precedence. I suggested instead
    > that the `typeof' keyword be followed by space so as to indicate it is
    > an operator and not, as its being followed directly by a parenthesed
    > expression would indicate, a method. (Of course, if parentheses are
    > not used, that would require `typeof' to be followed by whitespace,
    > else it would not be parsed as a keyword.)


    Yes, I agree with that.
     
    David Mark, Dec 10, 2007
    #18
  19. On Dec 8, 11:30 am, Thomas 'PointedEars' Lahn <>
    wrote:
    > David Mark wrote:
    > > On Dec 8, 12:22 pm, Thomas 'PointedEars' Lahn <>
    > > wrote:
    > >> David Mark wrote:
    > >>> On Dec 8, 11:07 am, Thomas 'PointedEars' Lahn <> wrote:
    > >>>> David Mark wrote:
    > >>>>> On Dec 8, 9:33 am, Thomas 'PointedEars' Lahn <>
    > >>>>> wrote:
    > >>>>>> David Mark wrote:
    > >>>>>>> I see the "When is a function not a function" thread has flared
    > >>>>>>> up again. This is what I use to test parameters that can be
    > >>>>>>> Functions or Objects. It does return the expected result for
    > >>>>>>> callable host objects (at least the ones I tested.) None of the
    > >>>>>>> functions it supports are expected to receive those as
    > >>>>>>> parameters. The second part of the test is a little ambiguous in
    > >>>>>>> this regard (for browsers that do not support call), so it is
    > >>>>>>> best to exclude callable host objects as a rule. var isFunction =
    > >>>>>>> function(o) { return typeof(o) == 'function' &&
    > >>>>>>> (!Function.prototype.call || typeof(o.call) == 'function'); };
    > >>>>>> isFunction() will return `false' where Function.prototype.call is
    > >>>>>> not supported and the object has no `call' property, even though
    > >>>>>> the argument referred to a Function object. That is the case in
    > >>>>>> JavaScript before
    > >>>>> If it is a Function then the first part of the conjunction is true.
    > >>>>> The second part will also be true as !Function.prototype.call will
    > >>>>> evaluate to true when call is not supported. So just what are you
    > >>>>> talking about?
    > >>>> Sorry, I have confused matters here. However, I would like to point
    > >>>> out that it does not make sense to test against
    > >>>> Function.prototype.call, be it in the negative direct or the positive
    > >>>> indirect way. That the object has a(n *external*) `call' property has
    > >>>> nothing to do with whether or not it is callable (with an argument
    > >>>> list), having an *internal* [[Call]] method.
    > >>> It is not meant to return true for anything but Functions. It is not an
    > >>> isCallable function.
    > >> Again, if I already knew that the argument is a reference to a Function
    > >> object, I would not need (to call) your method. Because Function objects

    >
    > > You apparently haven't been paying attention.

    >
    > It is certain now that you don't know what you are doing.
    >
    > > Let me try to simplify this for you. This function for my purposes
    > > could be as simple as:

    >
    > > typeof(o) == 'function'


    David, then why isn't the function that simple?


    > Exactly my point. You don't need a function to test that at all.


    "PointedEars", would you recommend simply writing typeof(o) ==
    'function' inline where David would write the function call?


    > A function that will also have the drawback, as compared to the already
    > available alternative, of requiring the caller to provide a qualified reference.


    I can see this point. I think David is suggesting he always knows that
    the 'o' variable is at least declared and so the call to the wrapper
    function will not error.


    [snip]

    --
    Peter
    Code Worth Recommending Project
    http://cljs.michaux.ca
     
    Peter Michaux, Dec 12, 2007
    #19
  20. On Dec 10, 5:38 am, "Thomas 'PointedEars' Lahn" <>
    wrote:
    > RobG wrote:
    > > 1. For host methods (aka feature detection), use:

    >
    > > if (hostObj && hostObj.method) {
    > > hostObj.method();
    > > }

    >
    > I don't think so, and I have already explained why.



    Suppose you wanted to wrap document.getElement by id in a function
    with the same intent as this

    function getEBI(id, doc) {
    return (doc || document).getElementById(id);
    }

    How would you rewrite this to use feature detection? From your posts I
    expect you will somehow check for the existance of document,
    document.getElementById and that document.getElementById is callable.
    Does your technique account for the possibility that document may be
    implemented sometime in the future by IE as an ActiveX object?

    I look forward to reading your response. Thanks.

    [snip]

    --
    Peter
    Code Worth Recommending Project
    http://cljs.michaux.ca
     
    Peter Michaux, Dec 12, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Peter Michaux
    Replies:
    45
    Views:
    395
    Peter Michaux
    Dec 7, 2007
  2. Peter Michaux
    Replies:
    16
    Views:
    250
    Peter Michaux
    Nov 26, 2007
  3. David Mark
    Replies:
    152
    Views:
    859
  4. Peter Michaux
    Replies:
    0
    Views:
    160
    Peter Michaux
    Dec 13, 2007
  5. Peter Michaux
    Replies:
    24
    Views:
    320
Loading...

Share This Page