The question about setTimeout

the specific problem is that when executing the method itself in setTimeout, writing the method name directly will report an error. Maybe I searched in the wrong way and did not find the relevant answer.
this.timer = setTimeout (self.change, this.s); if you write this, you will get an error.
write this in order to keep changing the font color.

function ChangeColor(id,arr,s) {
    this.id = id;
    this.arr = arr;
    this.s = s;
    this.i = 0;
    this.timer = null;
}

ChangeColor.prototype = {
    change : function () {
        let self = this;
        if (this.arr[this.i]) {
            $(this.id).css("color", this.arr[this.i]);
        }

        this.i === 0 ? this.iPP : this.i = 0;
        // this.timer = setTimeout(self.change, this.s);
        this.timer = setTimeout(function () {
            // console.log(self);
            self.change();
        }, this.s);
    }
};

let txt = new ChangeColor(".txt",["-sharpfff","-sharp000"],200);
txt.change();

Thank you

Mar.20,2021

you are recursive.
Recursive words have no boundary, and memory will jump after running for a while.
call


with a timer outside the change function
//
this.timer = setTimeout(this.change.bind(this), this.s);

initialization runs normally. After the timer is triggered, the change function is used as the callback function of setTimeout. In this case, this points to window, to execute this.arr [this.i] error.

finally, the function call is txt.change () , not txt.changeColor ()


The

upstairs is right. This is about the direction of this . To make it clear that this is bound at run time, not at writing time, its context depends on various conditions when the function is called. The binding of this has nothing to do with the location of the function declaration, only depends on how the function is called. Specifically, you can take a look at my summary of a reading note JavaScript basic series-beating this

.

when txt.change () is called directly for the first time, this points to txt object, so self also points to txt object, so initialization runs normally. The callback location of the
setTimeout is always in the global scope, so the this in the callback points to the global object-there are window objects in the browser. Now you use self.change as the callback of setTimeout . After the timer is triggered, the this in the callback self.change points to window . So when you execute if (this.arr [this.i]) , you will get an error: Cannot read property 'undefined' of undefined


if you just need to achieve this effect, not necessarily in your way, you can use a loop timer to trigger.
then manipulate the specific object attribute values in the corresponding processing to achieve the effect.


What is said above is right, which is about the direction of this. To make it clear that this is bound at run time, not at writing time, its context depends on various conditions when the function is called. The binding of this has nothing to do with the location of the function declaration, only depends on the way the function is called. Specifically, you can take a look at my summary of a basic series of reading notes on JavaScript-- beating this

.
txt.change()

when called directly for the first time, this points to the object txt, so self also points to the object txt, so initialization works fine. The calling location of the callback of
setTimeout is always in the global scope, so the this in the callback points to the global object-the window object in the browser, and now you use self.change as the callback of setTimeout, so when the timer is triggered, the this in the callback self.change points to window, while window does not have the attribute of arr,i, so an error: Cannot read property 'undefined' of undefined

will be reported when executing if (this.arr [this.i]).
Menu