Friday, January 2, 2009

[jQuery] Re: setInterval(obj.method,200) problem: scoping?

Thanks a lot Peter, that function is really neat !

On Sat, Jan 3, 2009 at 2:25 AM, pete higgins <phiggins@gmail.com> wrote:
>
> Here is your orig snippet rewritten to use the rescope function I pasted:
>
> var datascape = {
> 'mouseX': 0,
> 'myInterval': 0,
> 'create': function(){
> $('#datascape').bind('mousemove', rescope(this, function(e)
> {
> this.mouseX = e.pageX;
> })).bind("mouseover", rescope(this, function()
> {
> this.myInterval = setInterval(rescope(this, "move"), 200);
>
> })).bind("mouseout", rescope(this, function()
> {
> clearInterval(this.myInterval);
> }));
> },
>
> 'move': function(){
> $.log('datascape.move : mouseX = ' + this.mouseX);
> }
> }
>
> Though I didn't test it ...
>
> You are calling window.datascape.move still in the "window scope",
> when you want the scope (this) to be retained throughout your function
> calls. Saving a ref to it (var self = this) and accessing it in a
> function is still the solution. rescope is just that wrapped in a
> function for sugar (more or less). By passing 'this' to the rescope()
> function, you are effectively doing the same as self = this;
> function(){ self.foo(); } .. I find it much cleaner (the non-stripped
> version of rescope() allows for passing an ambigious number of
> parameters to the rescope'd function) and easier to work with when I'm
> explicitly setting the execution scope.
>
> Regards,
> Peter Higgins
>
> On Fri, Jan 2, 2009 at 8:06 PM, Alexandre Plennevaux
> <aplennevaux@gmail.com> wrote:
>>
>> Michael, did you know that i 'm becoming a big fan of your explanations?
>>
>> if i follow your explanation correctly, this should have worked, isn't it ?
>>
>> datascape.myInterval = setInterval(window.datascape.move,400);
>>
>> Yet it didn't. I guess i 'm kind of assimilating the javascript window
>> object to actionscript's _root object, and that assumption is probably
>> plain wrong :)
>>
>>
>> On Fri, Jan 2, 2009 at 11:49 PM, Michael Geary <mg@mg.to> wrote:
>>>
>>> Hi Alexandre,
>>>
>>> Don't go adopting a coding practice just because of a single mailing list
>>> message. :-)
>>>
>>> There's nothing wrong with quoting property names in an object literal, but
>>> the majority of experienced JavaScript programmers do not quote them except
>>> when necessary. As an example, browse through the jQuery source code:
>>>
>>> http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js
>>>
>>> Most of the property names in the code are not quoted, except for those few
>>> that are invalid identifiers or reserved words.
>>>
>>> Regarding setTimeout and setInterval, a minor nitpick on terminology:
>>> "setTimeout and setInterval scope the called function to the window object".
>>> Actually, the *scope* of the called function is determined by its position
>>> in the source code. JavaScript uses lexical scoping, where a nested function
>>> can directly refer to variables declared in outer functions or in the global
>>> scope. That's why your setInterval callback is able to use your thisObj
>>> variable, because the interpreter follows the scope chain from the inner
>>> function up to the outer function and finds the variable there.
>>>
>>> What you're talking about is the value of "this" in the setInterval
>>> callback. setInterval and setTimeout call your callback function as a method
>>> of the global object (which is the window object in a browser). Or another
>>> way to put it is that they don't call the function as a method of any object
>>> at all, and by default "this" is set to the global object.
>>>
>>> In any case, terminology nitpicks aside, your code is the right way to solve
>>> the problem! :-)
>>>
>>> -Mike
>>>
>>>> From: Alexandre Plennevaux
>>>>
>>>> hi donb, according to a lengthy discussion we had on this
>>>> mailinglist yesterday the quotes are good practice. see:
>>>> http://groups.google.com/group/jquery-en/msg/821f4eb134c51d3d
>>>> (is is just one message on a 31-long thread, if u have time
>>>> ,read the whole thread it is interesting )
>>>>
>>>> As for this issue after extensive googling i found out that
>>>> setTimeout and setInterval scope the called function to the
>>>> window object, not the object the setinterval is called in.
>>>>
>>>> Therefore here is how to do it:
>>>>
>>>> var datascape = {
>>>> 'mouseX': 0,
>>>> 'myInterval': 0,
>>>> 'create': function(){
>>>>
>>>> var thisObj = this; //<-- store this object instance in a variable
>>>>
>>>> $('#datascape').bind('mousemove', function(e)
>>>> {
>>>> this.mouseX = e.pageX;
>>>> }).bind("mouseover", function()
>>>> {
>>>> datascape.myInterval = setInterval(function() {
>>>> thisObj.move(); }, 1000); // <-- use the vairable
>>>> referencing the instance
>>>>
>>>> }).bind("mouseout", function()
>>>> {
>>>> clearInterval(datascape.myInterval);
>>>> });
>>>> },
>>>>
>>>> 'move': function(){
>>>> $.log('datascape.move : mouseX = ' + this.mouseX);
>>>> }
>>>> }
>>>>
>>>> On Thu, Jan 1, 2009 at 3:46 PM, donb
>>>> <falconwatcher@comcast.net> wrote:
>>>> >
>>>> > You should change 'move' to move (remove apostrophes).
>>>> >
>>>> >
>>>> > On Jan 1, 9:01 am, "Alexandre Plennevaux" <aplennev...@gmail.com>
>>>> > wrote:
>>>> >> Hello mates,
>>>> >>
>>>> >> i have an object datascape which among other things, contains a
>>>> >> property storing the mouse position, and a function that uses that
>>>> >> property. Inside another method i
>>>> >>
>>>> >> var datascape = {
>>>> >> 'mouseX': 0,
>>>> >> 'myInterval': 0,
>>>> >> 'create': function(){
>>>> >> $('#datascape').bind('mousemove', function(e)
>>>> >> {
>>>> >> this.mouseX = e.pageX;
>>>> >> }).bind("mouseover", function()
>>>> >> {
>>>> >> this.myInterval = setInterval(this.move, 200);
>>>> >>
>>>> >> }).bind("mouseout", function()
>>>> >> {
>>>> >> clearInterval(this.myInterval);
>>>> >> });
>>>> >> },
>>>> >>
>>>> >> 'move': function(){
>>>> >> $.log('datascape.move : mouseX = ' + this.mouseX);
>>>> >> }
>>>> >>
>>>> >> }
>>>> >>
>>>> >> Yet the script does not work:
>>>> >> firebug console points at the setInterval call, saying:
>>>> >>
>>>> >> useless setInterval call (missing quotes around
>>>> >> argument?)http://localhost/prototype/_js/frontend/proto.03.js
>>>> >> Line 172
>>>> >>
>>>> >> can someone help me / explain what i'm doing wrong ?
>>>> >>
>>>> >> Thank you,
>>>> >>
>>>> >> Alexandre
>>>> >>
>>>> >> PS: to all jquerians: happy 2009 !!
>>>>
>>>
>>>
>>
>

No comments: