Help using setInterval within an object function

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

    Help using setInterval within an object function

    Hi-

    I am trying to use setInterval to call a method within an object and
    have not had any luck. I get "Object doesn't support this property or
    method" when I execute the following code. What I am doing wrong?

    Your help will be much appreciated.
    Thanks


    <script language="Javas cript">

    function someObject(){
    }

    someObject.prot otype.showNext = function(){
    alert('listenin g...');
    }

    //i've tried this:
    someObject.prot otype.startList ening = function(){
    this.interval = setInterval('th is.showNext()', 2000);
    }

    //and this:
    someObject.prot otype.startList ening = function(){
    this.interval = setInterval(thi s.showNext(), 2000);

    /*

    is 'this.showNext( )' referencing setInterval and not my object?

    */


    }


    var x = new someObject();
    x.startListenin g();

    </script>

  • Baconbutty

    #2
    Re: Help using setInterval within an object function

    I am not sure that this helps, but:-

    OPTION 1
    [color=blue]
    >this.interva l = setInterval(thi s.showNext(), 2000);[/color]

    Remove the ( ) as these call the function. You want to pass a reference
    to the function instead, thus:

    this.interval = setInterval(thi s.showNext, 2000);

    OPTION 2

    Use a closure:-

    someObject.prot otype.startList ­ening = function()
    {
    this.interval = setInterval(sho wNext, 2000);

    function showNext()
    {
    alert('listenin g...');
    }
    }

    Julian

    Comment

    • Richard Cornford

      #3
      Re: Help using setInterval within an object function

      marktm wrote:[color=blue]
      > I am trying to use setInterval to call a method within an
      > object and have not had any luck. I get "Object doesn't
      > support this property or method" when I execute the
      > following code. What I am doing wrong?[/color]
      <snip>[color=blue]
      > <script language="Javas cript">[/color]

      The language attribute of script elements is deprecated in HTML 4, and
      the type attribute is required (rendering the language attribute
      redundant). Only attempting to script formally valid HTML removes an
      entire category of potential cross-browser scripting pitfalls (saves a
      lot of effort and trouble in the long run), but the script elements
      themselves need to be valid in order not to have the validator flag them
      as erroneous:-

      <script type="text/javascript">
      [color=blue]
      > function someObject(){
      > }
      >
      > someObject.prot otype.showNext = function(){
      > alert('listenin g...');
      > }
      >
      > //i've tried this:
      > someObject.prot otype.startList ening = function(){
      > this.interval = setInterval('th is.showNext()', 2000);[/color]

      Strings used as the first argument to setTimout/Interval are evaluated
      and executed in the global scope, and in the global scope the - this -
      keyword is a reference to the global object. The global object does not
      have a - showNext - method (unless you give it one) so that code will
      error, as described.
      [color=blue]
      > }
      >
      > //and this:
      > someObject.prot otype.startList ening = function(){
      > this.interval = setInterval(thi s.showNext(), 2000);[/color]

      But the behaviour was different here as this code put up the alert box,
      it did so when the setInterval function was fist called (and only once).

      This expression has called the - showNext - method of the object
      instance and it is the return value form that function call that is
      passed to the setInterval function as an argument. The - showNext -
      method returns - undefined - so the first argument to the setInterval
      function will likely be type converted into the string "undefined" ,
      which is a pointless expression when executed in the global context on
      more modern browsers, and an error (E.G.: IE 4 -> "undefined is
      undefined") on older ones.
      [color=blue]
      > /*
      >
      > is 'this.showNext( )' referencing setInterval and not my object?[/color]

      setInterval/Timeout has no knowledge of the context in which it is used.
      It's arguments are either a string that will be evaluated/executed in
      the global context, or a function reference where the function will be
      executed as a function (not as a method of an object, i.e. the - this -
      keyword will always refer to the global object).
      [color=blue]
      > }
      >
      > var x = new someObject();
      > x.startListenin g();
      >
      > </script>[/color]

      If the desire is to retain the association of the function call with an
      object instance (which is not worthwhile unless the method called
      actually refers to an object instance (uses the - this - keyword)), then
      with string arguments a globally accessible reference to the object
      instance would need to be created (or an existing one used). In this
      case you have a global variable - x - referring to the object instance
      so:-

      setInterval( "x.showNext();" , 1000);

      - would work, but be a terrible design as it would have made a detail of
      how the object was to be used internal to the object, and you would only
      be able to ever use one instance of the object (suggesting an entirely
      difference approach from the outset).

      To be useful the string argument would need to know how to refer to
      distinct object instances without any interest in how those objects were
      being employed by external code (anonymously).

      This can be done, for example, by having each object constructed create
      an unique global reference to itself. E.G:-

      function someObject(){
      this.index = someObject.inst ances.length;
      someObject.inst ances[this.index] = this;
      }

      someObject.inst ances = [];

      someObject.prot otype.startList ening = function(){
      this.interval = setInterval(
      'someObject.ins tances['+this.index+'].showNext()',
      2000
      );
      }

      - Which is a bit cumbersome, and leaves you with an array of all objects
      created (so they will not be garbage collected if otherwise freed,
      unless an explicit 'destroy' facility is provided and used to remove the
      references from the globally accessible array).

      Using function references as the first argument to setTimeout/Interval,
      while preserving the association with an object instance, is simpler to
      arrange and more complex to understand as it requires closures. See:-

      <URL: http://jibbering.com/faq/faq_notes/closures.html >

      And some older browsers do not understand function references as the
      first argument to the setTimeout/Interval functions, only strings
      (though that can be worked around).

      Richard.


      Comment

      • Baconbutty

        #4
        Re: Help using setInterval within an object function

        OPTION 3

        Sorry, taking account of what Richard has said, a more accurate example
        of a closure would be:-

        someObject.prot otype.showNext = function()
        {
        alert('listenin g...');
        };

        someObject.prot otype.startList ­­ening = function()
        {
        var oInstance=this; // CAPTURE THIS

        this.interval = setInterval(fun ction(){oInstan ce.showNext()},
        2000);
        // oINSTANCE IS "CLOSED" INSIDE THE ANONYMOUS FUNCTION
        };

        Comment

        • marktm

          #5
          Re: Help using setInterval within an object function

          Thanks!

          Comment

          • Jimnbigd

            #6
            Re: Help using setInterval within an object function

            Use the 2nd way, but leave off the parentheses:
            this.interval = setInterval(thi s.showNext, 2000);
            Reason:
            Method 1 fails because it is interpretted as a function called "this" -- it
            is in quotes.
            Method 2 fails because with the parentheses and not in quotes, the function
            is executed immediately, and in fact could return another function as the
            value to be "called".
            Clear, sort of?
            ....Jim Lee, Dallas, TX...

            "marktm" <marktm@gmail.c om> wrote in message
            news:1115693985 .408834.12490@z 14g2000cwz.goog legroups.com...[color=blue]
            > Hi-
            >
            > I am trying to use setInterval to call a method within an object and
            > have not had any luck. I get "Object doesn't support this property or
            > method" when I execute the following code. What I am doing wrong?
            >
            > Your help will be much appreciated.
            > Thanks
            >
            >
            > <script language="Javas cript">
            >
            > function someObject(){
            > }
            >
            > someObject.prot otype.showNext = function(){
            > alert('listenin g...');
            > }
            >
            > //i've tried this:
            > someObject.prot otype.startList ening = function(){
            > this.interval = setInterval('th is.showNext()', 2000);
            > }
            >
            > //and this:
            > someObject.prot otype.startList ening = function(){
            > this.interval = setInterval(thi s.showNext(), 2000);
            >
            > /*
            >
            > is 'this.showNext( )' referencing setInterval and not my object?
            >
            > */
            >
            >
            > }
            >
            >
            > var x = new someObject();
            > x.startListenin g();
            >
            > </script>
            >[/color]


            Comment

            • Richard Cornford

              #7
              Re: Help using setInterval within an object function

              Jimnbigd wrote:[color=blue]
              > Use the 2nd way, but leave off the parentheses:
              > this.interval = setInterval(thi s.showNext, 2000);[/color]

              Which will loose the association with the object instance and so be
              useless in real world examples.
              [color=blue]
              > Reason:
              > Method 1 fails because it is interpretted as a function
              > called "this" -- it is in quotes.[/color]
              <snip>

              Nothing is interpreted 'as a function called "this"', the - this -
              keyword, in this context, is interpreted as a reference to the global
              object, and - this.showNext - is interpreted as a property of the global
              object. Because that property is not defined an error is generated when
              it is called as a method.

              If you are going to post answers to questions that have already been
              answered twice it would be a good idea to read and understand the other
              answers, and not be posting responses that are factually wrong and
              disregard an important detail that has been covered in those other
              answers.
              [color=blue]
              > "marktm" <marktm@gmail.c om> wrote ...[/color]
              <snip>

              Please do not top-post on comp.lang.javas cript, see the FAQ for details.

              Richard.


              Comment

              Working...