isFunction (Code Worth Recommending Project)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • David Mark

    isFunction (Code Worth Recommending Project)

    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.prot otype.call ||
    typeof(o.call) == 'function');
    };
  • Thomas 'PointedEars' Lahn

    #2
    Re: isFunction (Code Worth Recommending Project)

    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.prot otype.call ||
    typeof(o.call) == 'function');
    };
    isFunction() will return `false' where Function.protot ype.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$8 300dec7@news.de mon.co.uk>

    Comment

    • Peter Michaux

      #3
      Re: isFunction (Code Worth Recommending Project)

      On Dec 8, 11:05 am, David Mark <dmark.cins...@ gmail.comwrote:
      On Dec 8, 12:22 pm, Thomas 'PointedEars' Lahn <PointedE...@we b.de>
      wrote:
      >
      >
      >
      David Mark wrote:
      On Dec 8, 11:07 am, Thomas 'PointedEars' Lahn <PointedE...@we b.dewrote:
      >David Mark wrote:
      >>On Dec 8, 9:33 am, Thomas 'PointedEars' Lahn <PointedE...@we b.de>
      >>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
      >>>>parameter s. 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.protot ype.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.proto type.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.proto type.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

      Comment

      • Peter Michaux

        #4
        Re: isFunction (Code Worth Recommending Project)

        On Dec 8, 10:32 pm, RobG <rg...@iinet.ne t.auwrote:
        Peter Michaux wrote:
        On Dec 8, 11:05 am, David Mark <dmark.cins...@ gmail.comwrote:
        >
        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

        Comment

        • RobG

          #5
          Re: isFunction (Code Worth Recommending Project)

          Peter Michaux wrote:
          On Dec 8, 10:32 pm, RobG <rg...@iinet.ne t.auwrote:
          >Peter Michaux wrote:
          >>On Dec 8, 11:05 am, David Mark <dmark.cins...@ gmail.comwrote:
          >>>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
          >>foundationa l 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

          Comment

          • David Mark

            #6
            Re: isFunction (Code Worth Recommending Project)

            On Dec 9, 1:52 am, Peter Michaux <petermich...@g mail.comwrote:
            On Dec 8, 10:32 pm, RobG <rg...@iinet.ne t.auwrote:
            >
            Peter Michaux wrote:
            On Dec 8, 11:05 am, David Mark <dmark.cins...@ gmail.comwrote:
            >
            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 isFeaturedMetho d in the gEBI wrapper thread.

            Comment

            • David Mark

              #7
              Re: isFunction (Code Worth Recommending Project)

              On Dec 9, 2:20 am, RobG <rg...@iinet.ne t.auwrote:
              Peter Michaux wrote:
              On Dec 8, 10:32 pm, RobG <rg...@iinet.ne t.auwrote:
              Peter Michaux wrote:
              >On Dec 8, 11:05 am, David Mark <dmark.cins...@ gmail.comwrote:
              >>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 reFeaturedMetho d = new RegExp('^functi on|object$', 'i');

              var isFeaturedMetho d = function(o, m) {
              var t = typeof(o[m]);
              return !!((reFeaturedM ethod.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.

              Comment

              • Thomas 'PointedEars' Lahn

                #8
                Re: isFunction (Code Worth Recommending Project)

                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

                Comment

                • David Mark

                  #9
                  Re: isFunction (Code Worth Recommending Project)

                  On Dec 10, 8:38 am, "Thomas 'PointedEars' Lahn" <PointedE...@we b.de>
                  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.

                  Comment

                  • Peter Michaux

                    #10
                    Re: isFunction (Code Worth Recommending Project)

                    On Dec 8, 11:30 am, Thomas 'PointedEars' Lahn <PointedE...@we b.de>
                    wrote:
                    David Mark wrote:
                    On Dec 8, 12:22 pm, Thomas 'PointedEars' Lahn <PointedE...@we b.de>
                    wrote:
                    David Mark wrote:
                    >On Dec 8, 11:07 am, Thomas 'PointedEars' Lahn <PointedE...@we b.dewrote:
                    >>David Mark wrote:
                    >>>On Dec 8, 9:33 am, Thomas 'PointedEars' Lahn <PointedE...@we b.de>
                    >>>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
                    >>>>>Function s or Objects. It does return the expected result for
                    >>>>>callable host objects (at least the ones I tested.) None of the
                    >>>>>function s 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.protot ype.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
                    >>>>JavaScrip t before
                    >>>If it is a Function then the first part of the conjunction is true.
                    >>>The second part will also be true as !Function.proto type.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.prot otype.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.
                    "PointedEar s", 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

                    Comment

                    • David Mark

                      #11
                      Re: isFunction (Code Worth Recommending Project)

                      On Dec 11, 7:13 pm, Peter Michaux <petermich...@g mail.comwrote:
                      [snip]
                      >
                      typeof(o) == 'function'
                      >
                      David, then why isn't the function that simple?
                      The original discussion "When is a function not a function" concerned
                      a function of mine that could receive a Function or Object object as a
                      callback parameter. The specifics were that it would call a
                      predetermined method on Object objects. If a callable host object
                      (typeof(o) == 'function') is passed, which would be a violation of the
                      rules, it should not call it and therefore fail silently. This posted
                      version is the solution for that. It will not mistake callable host
                      objects (or builtin functions) for suitable callback Functions. It
                      will fail instantly if passed an inappropriate callback parameter.

                      Is it of any practical use? Not for me at this time as I don't handle
                      callbacks that way anymore. It did spark a lot of discussion in the
                      original thread though.

                      [snip]
                      >
                      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.
                      Exactly.

                      Comment

                      • Peter Michaux

                        #12
                        Re: isFunction (Code Worth Recommending Project)

                        On Dec 9, 3:09 am, David Mark <dmark.cins...@ gmail.comwrote:
                        On Dec 9, 2:20 am, RobG <rg...@iinet.ne t.auwrote:
                        [snip]
                        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.
                        [snip]
                        This is a partial solution to feature testing host methods. This is
                        what I use:
                        >
                        var reFeaturedMetho d = new RegExp('^functi on|object$', 'i');
                        >
                        var isFeaturedMetho d = function(o, m) {
                        var t = typeof(o[m]);
                        return !!((reFeaturedM ethod.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.
                        Is there a particular need to involve a regular expression?

                        When would "reFeaturedMeth od.test(t)" be true but o[m] would be falsy?

                        Which situation does the "t=='unknow n'" cover? It seems odd that if
                        typeof(o[m]) is "unknown" then I should believe that o[m] is a
                        callable method.

                        I think I'm catching up on this stuff.

                        --
                        Peter
                        Code Worth Recommending Project

                        Comment

                        • Peter Michaux

                          #13
                          Re: isFunction (Code Worth Recommending Project)

                          On Dec 11, 4:34 pm, David Mark <dmark.cins...@ gmail.comwrote:
                          On Dec 11, 7:13 pm, Peter Michaux <petermich...@g mail.comwrote:
                          [snip]
                          >
                          >
                          >
                          typeof(o) == 'function'
                          >
                          David, then why isn't the function that simple?
                          >
                          The original discussion "When is a function not a function" concerned
                          a function of mine that could receive a Function or Object object as a
                          callback parameter. The specifics were that it would call a
                          predetermined method on Object objects. If a callable host object
                          (typeof(o) == 'function') is passed, which would be a violation of the
                          rules, it should not call it and therefore fail silently. This posted
                          version is the solution for that. It will not mistake callable host
                          objects (or builtin functions) for suitable callback Functions. It
                          will fail instantly if passed an inappropriate callback parameter.
                          So your callback was actually being called as

                          callback.call(o bj, arg1, arg2)

                          and you really needed to insure that there was a .call() property?

                          Thanks

                          --
                          Peter
                          Code Worth Recommending Project

                          Comment

                          • David Mark

                            #14
                            Re: isFunction (Code Worth Recommending Project)

                            On Dec 11, 7:37 pm, Peter Michaux <petermich...@g mail.comwrote:
                            On Dec 9, 3:09 am, David Mark <dmark.cins...@ gmail.comwrote:
                            >
                            On Dec 9, 2:20 am, RobG <rg...@iinet.ne t.auwrote:
                            >
                            [snip]
                            >
                            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.
                            >
                            [snip]
                            >
                            This is a partial solution to feature testing host methods. This is
                            what I use:
                            >
                            var reFeaturedMetho d = new RegExp('^functi on|object$', 'i');
                            >
                            var isFeaturedMetho d = function(o, m) {
                            var t = typeof(o[m]);
                            return !!((reFeaturedM ethod.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.
                            >
                            Is there a particular need to involve a regular expression?
                            >
                            When would "reFeaturedMeth od.test(t)" be true but o[m] would be falsy?
                            If o[m] is null.
                            >
                            Which situation does the "t=='unknow n'" cover? It seems odd that if
                            typeof(o[m]) is "unknown" then I should believe that o[m] is a
                            callable method.
                            ActiveX methods. "Unknown" may seem an odd type, but is actually
                            appropriate if you dig into ActiveX (COM) interfaces. That is the LCD
                            interface that all ActiveX objects implement. You can't tell anything
                            about the object from that interface, other than it is an ActiveX
                            object.

                            Comment

                            Working...