When you write a program in the Wolfram Language, you should always try to set it up so that its parts are as independent as possible. In this way, the program will be easier for you to understand, maintain, and add to.
One of the main ways to ensure that different parts of a program do not interfere is to give their variables only a certain "scope". The Wolfram Language provides two basic mechanisms for limiting the scope of variables: modules and blocks.
Most traditional computer languages use a so‐called "lexical scoping" mechanism for variables, which is analogous to the module mechanism in the Wolfram Language. Some symbolic computer languages such as LISP also allow "dynamic scoping", analogous to Wolfram Language blocks.
When lexical scoping is used, variables are treated as local to a particular section of the code in a program. In dynamic scoping, the values of variables are local to a part of the execution history of the program.
In compiled languages like C and Java, there is a very clear distinction between "code" and "execution history". The symbolic nature of the Wolfram Language makes this distinction slightly less clear, since "code" can in principle be built up dynamically during the execution of a program.
What Module[vars,body] does is to treat the form of the expression body at the time when the module is executed as the "code" of a Wolfram Language program. It examines the expression, and when any of the vars explicitly appears in this "code", it is considered to be local. Normal evaluation then proceeds.
Block[vars,body] does not look at the form of the expression body. Instead, it records the current value of each of the vars. Throughout the evaluation of body, the block uses local values for the vars, and then restores their original values once the evaluation of body is finished.