How to Use setInterval to call the Class Method

Source: Internet
Author: User

The setInterval () method can call functions or computation expressions according to the specified period (in milliseconds. The setInterval () method does not stop calling the function until clearInterval () is called or the window is closed. The ID value returned by setInterval () can be used as a parameter of the clearInterval () method.

Recently, when writing a program, it is found that the correct class method cannot be obtained when the setInterval passed in method is called at the program interval. The reason is that JS has flexible this pointer rebinding. So why does this pointer rebind and rebind to it? What does setInterval do?

As we all know, JS classes are simulated by functions, but they are not really object-oriented classes, so we should start from here. The JS simulation methods are roughly divided into three forms: the first is typical for HW developers, and the prototype extension simulation class; the second is the anonymous object extension simulation class; the third method is to create classes dynamically using functions. This method can be mapped to the reflection mechanism in object-oriented language. This is similar. Of course, the focus of today is not this. Let's go back to our topic. To understand the this pointer, let's look at an example:

function getName(){    return this.name;}function Person(){     this.name = "sparon";}Person.prototype.sayName = getName;var people = new Person();people.sayName();result:sparon

This example shows that this pointer is bound later than it was bound during program initialization. In "7.2.2 about this object" in JAVASCRIPT advanced programming, this object is bound to the execution environment of the function at runtime ". This is the globally unique special pointer, and this is the internal call flag of the class. It is invalid when we call the this pointer inside the class.

Well, after clarifying this point, we will go back and talk about the setInterval function. In fact, setInterval is actually a method of the widnow object, and the window object is also a special object, I will discuss it later.

Syntax: setInterval (code, millisec [, "lang"])

  • Code: required. The function to be called or the code string to be executed.
  • Millisec: required. The interval between periodical execution or call codes, in milliseconds.

The following parameters are basically not used, so we will not explain them here.

Here code can be a function name, a function name string, a piece of code, or an anonymous function, which is the flexibility of the JS language. Of course, milisec is the call interval. The code parameter is described below.

Let's take a look at the call I made early in the morning. Let's take a look at the problem and think about whether the this pointer in gameStart and gameLoop points to that object, and whether it is the same object, if not why.

Function SPARONGame () {this. name = "DotaAllStar"; this. player_Num = 10; this. game_init = false; this. game_start = false; this. game_speed= 100;} SPARONGame. prototype. init = function () {// Todo init game... $ ("# start "). click (this. gameStart); this. game_init = true;} SPARONGame. prototype. gameStart = function () {if (! This. game_init) {// If you call this. game_init here, there will be a problem. What is the problem? Where does this point again? Return;} this. game_start = true; setInterval (this. gameLoop, this. game_speed);} SPARONGame. prototype. gameLoop = function () {if (! This. game_start) {// If you call this. game_start here, there will be a problem. What is the problem? Where does this point again? Return ;}}

The most critical issue in this code is the scope problem. To solve this problem, first understand where the this Pointer Points? First, this in gameStart points to the document object, because when $ ("# start") is executed "). click (this. gameStart); click actually processes gameStart as a function, so when the user clicks the start tag of the page, JS binds the gameStart function to the document Object. In gameLoop, this points to the window, and the principle is the same. As for why, we should review the previous example. Previously we mentioned that this pointer is dynamically bound late.

So how can I fix this? The JS namespace will be used here. It is because this is bound late, And when gameStart and gameLoop pass the object method to the event processing function, JS cannot dynamically parse or change this to the object to which it points, resulting in calling this parameter later. this is rebound. There are many solutions. I have seen an article on the Internet that sets this object to a window object through the eval function so that it can be accessed globally, it can be used normally after it is retrieved inside the call method. Another method is very simple, that is, to store pointer reference using variables, and then call the method through variables in anonymous functions, the third is the solution I mentioned, which is located through the namespace.

In JS, the dot (.) usually indicates the class. method/field /..., However, we can understand from the other hand that in terms of point operator time, apart from the Object-Oriented function, we can use the point operator as the path marker of the namespace, when we send a specific instance class, the JS interpreter can easily find the method we want and know that the method is under the specific instance. Well, let's take a look at it, I will make a slight change to the above example.

var SPARONGame = {    name : "DotaAllStar",    player_Num : 10,    game_init : false,    game_start : false,    game_speed : 100,    init : function() {        // Todo init game...        $("#start").click(this.gameStart);        this.game_init = true;    },    gameStart : function(){        if (!SPARONGame.game_init) {            return;        }        SPARONGame.game_start = true;        setInterval("SPARONGame.gameLoop()", SPARONGame.game_speed);    },    gameLoop : function() {        if (!this.game_start){            return;        }    }}

In this Code, you must note that the first parameter of setInterval is a string, not a class name. method name. Otherwise, the final result will still be passed in as a function.

After solving the above problems, I will briefly mention the two bugs in setInterval. Although they are very subtle, you must know that, otherwise, a major problem will occur when writing a program to handle the boundary issue. 1. some intervals will be skipped; 2. the interval between code execution of multiple timers may be smaller than expected, for detailed answers to these two questions, refer to the "18.2.1 repeated timer" section in JavaScript advanced programming.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.