A little doubt about javascript setInterval callback letter

I am a novice. I encountered a little confusion when learning javascript timer. It may be a clich problem, but I still want to ask the elders. The problem and code are as follows:

var Cat = function() {
    var o = {
        say: function() {
            console.log("say something");
        }
    }
    setInterval(function(){
        o.say()
    }, 1000)
    return o
}

var cat = Cat()

cat.say = function() {
    console.log("Hello");
}

problem description:
I defined a Cat class (factory mode used), and then this class has a method say () , and a setInterval executes the "method", then instantiates the class and redeclares the say () method.

my confusion:
is that the output is" Hello", not the method in the class I defined in the first place. This place doesn"t really understand

.

personal understanding:
because the return function passed in setInterval is a method, in fact, that o refers to the instantiated instance object, not the original class?

but I feel like I understand a little, but I don"t understand it, or I don"t understand it at all. I hope you seniors can have a detailed answer on how to correctly and clearly understand the running process of this code.


o is an instantiated object. Every time you execute Cat , a new o is generated. The instantiation of o is completed after var o =. is executed.

try the following code:

var Cat = function() {
    var o = {
        say: function() {
            console.log('say something');
        }
    }
    let say = o.say;
    setInterval(function(){
        say();
    }, 1000)
    return o
}

var cat = Cat()

cat.say = function() {
    console.log('Hello');
}

then the output is

Say something
The problem of

has nothing to do with setInterval . The callback function of setInterval in the code you provided holds a reference to the instance of o , not to o.say . Therefore, when this callback is executed a second later, you will find o first, and then look for o.say . The callback function of setInterval in the code I provided holds a reference to the o.say function, and is a reference to the old o.say , so when the callback is executed a second later, it will directly find the old o.say .

I don't know if this is clear to you.


first executes the function Cat () , defines the say () method in the object, and then encounters setInterval , which is an asynchronous task, so join the asynchronous queue. Then execute cat.say = function () {console.log ('Hello'} ), at which point the say method of the instance object cat has been overridden. Next, the Synchronize task is finished, and the callback function is added to the asynchronous queue before execution, so the output is Hello .


to output 'say something', the key is to run the exact reference to o in Cat in the timer callback, or you can do this:

var Cat = function() {
var another;
    var o = {
        say: function() {
            console.log('say something');
        }
    }
    another = o.say;
    setInterval(function(){
        another ();
    }, 1000)
    return o
}



The

code is simplified to

var o = {
    say: function() {
        console.log('say something');
    }
}
setInterval(function(){
    o.say()
}, 1000);
var cat = o;

cat.say = function() {
    console.log('Hello');
}

draw a picture:

flow.png

    The
  1. o and Cat variables both point to the 0x0001 address, where an object is stored;
  2. There is a say pointer to 0x0002 on the
  3. object, where is the say function;
  4. later, the say pointer is reassigned to the 0x0003 address, which is a new say function;
  5. finally, the setInterval function calls 0x0003's say function, not 0x0002's say function.

although the code for setInterval is written first, it will be executed first because the first three steps are Synchronize tasks.
you can search for the event loop in JS. The Synchronize task code is executed first, and macro tasks such as setInterval and setTimeout are placed in an asynchronous queue to wait for the Synchronize task to complete.

MySQL Query : SELECT * FROM `codeshelper`.`v9_news` WHERE status=99 AND catid='6' ORDER BY rand() LIMIT 5
MySQL Error : Disk full (/tmp/#sql-temptable-64f5-1bed0a2-31b31.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
MySQL Errno : 1021
Message : Disk full (/tmp/#sql-temptable-64f5-1bed0a2-31b31.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
Need Help?