1. var variable pre-compilation
The syntax of JavaScript is similar to C, Java, and C#, collectively referred to as C-like syntax. Students who have experience in C or Java programming should be familiar with the rule of "declare first, use later". If you use undeclared variables or functions, an error will be reported during the compilation phase. However, JavaScript can use variables and functions before they are declared. Let’s take a closer look at the mystery below.
Let’s look at a piece of code first:
(function() { console.log(noSuchVariable);//ReferenceError: noSuchVariable is not defined })();
Run the above code and an error will be reported immediately. However, this is exactly what we expected, because the noSuchVariable variable has not been defined at all! Let’s take a look at the following code:
(function() { console.log(declaredLater); //undefined var declaredLater = "Now it's defined!"; console.log(declaredLater);// "Now it's defined!" })();
First of all, the above code is correct and there is no problem. But why is it not reporting an error? The declaredLater variable is defined after the calling statement? Why is the output undefined?
This is actually caused by the JavaScript parser. The parser places all variables and functions declared in the current scope at the beginning of the scope. However, only the declaration of variables is advanced to the beginning of the scope. The assignment operations are left in place. The above code actually looks like this to the parser:
(function() { var declaredLater; //声明被提前到作用域开始处了! console.log(declaredLater); // undefined declaredLater = "Now it's defined!"; //赋值操作还在原地! console.log(declaredLater);//"Now it's defined!" })();
This is why the above code does not report an exception! After variables and functions are "advanced", the declaredLater variable is actually placed in front of the calling function. According to the definition of JavaScript syntax, variables that have been declared but not assigned will be automatically assigned to undefined. Therefore, the first print The value of the declaredLater variable is undefined. Later, we assigned a value to the declaredLater variable, so when we print the variable for the second time, Now it's defined! will be output.
Let’s look at another example:
var name = "Baggins"; (function () { console.log("Original name was " + name);// "Original name was undefined" var name = "Underhill"; console.log("New name is " + name);// "New name is Underhill" })();
In the above code, we first declare a variable name. Our original intention is to output the name variable defined in the global scope when printing the name variable for the first time, and then define a local name variable in the function to cover the global variables, and finally output the value of the local variable. However, the first output result is completely inconsistent with our expectations. The reason is that the local variables we defined are "advanced" within their scope, that is, they become the following form:
var name = "Baggins"; (function () { var name; //注意:name 变量被提前了! console.log("Original name was " + name);// "Original name was undefined" name = "Underhill"; console.log("New name is " + name);//"New name is Underhill" })();
Because JavaScript has such "quirks", it is recommended that you place the variable declaration at the top of the scope, so that you can always remind yourself to pay attention.
2. Function declaration is "advanced"
What I talked about earlier is variables, next let’s talk about functions.
There are two situations in which a function is "advanced", one is function declaration, and the second is function being assigned to a variable as a value, that is, a function expression.
Let’s talk about the first situation first, the code:
isItHoisted();//"Yes!" function isItHoisted() { console.log("Yes!"); }
As shown above, the JavaScript interpreter allows you to use it before the function declaration. In other words, the function declaration is not just the function name that is "advanced", but the entire function definition is also "advanced"! So the above code can be executed correctly.
Let’s look at the second case: function expression form. Let’s start with the code:
definitionHoisted();// "Definition hoisted!" definitionNotHoisted();// TypeError: undefined is not a function function definitionHoisted() { console.log("Definition hoisted!"); } var definitionNotHoisted = function () { console.log("Definition not hoisted!"); };
We made a comparison. The definitionHoisted function was properly executed, conforming to the first type; the definitionNotHoisted variable was "advanced", but its assignment (that is, the function) was not advanced. From this point of view That is to say, it is completely consistent with the "advancement" of variables we talked about earlier, and since the default value of the "advancement" variable is undefined, the error reported belongs to "type mismatch", because undefined is not a function, of course cannot be called.
Summary
Through the above explanation, it can be summarized as follows:
The declaration of variables is advanced to the top of the scope, and the assignment remains in place
The entire function declaration is "advanced"
When using a function expression, only the variable is "advanced", the function is not "advanced"
3. Side effects of var
A small difference between implicit global variables and explicitly defined global variables is the ability to leave variables undefined through the delete operator.
Global variables created through var (created in any program outside of functions) cannot be deleted.
Implicit global variables created without var (regardless of whether they are created in a function) can be deleted.
This shows that, technically, implicit global variables are not really global variables, but they are properties of the global object. Attributes can be deleted through the delete operator, but variables cannot:
// 定义三个全局变量 var global_var = 1; global_novar = 2; // 反面教材 (function () { global_fromfunc = 3; // 反面教材 }()); // 试图删除 delete global_var; // false delete global_novar; // true delete global_fromfunc; // true // 测试该删除 typeof global_var; // "number" typeof global_novar; // "undefined" typeof global_fromfunc; // "undefined"
在ES5严格模式下,未声明的变量(如在前面的代码片段中的两个反面教材)工作时会抛出一个错误。
4、单var形式声明变量
在函数顶部使用单var语句是比较有用的一种形式,其好处在于:
提供了一个单一的地方去寻找功能所需要的所有局部变量
防止变量在定义之前使用的逻辑错误
少代码(类型啊传值啊单线完成)
单var形式长得就像下面这个样子:
function func() { var a = 1, b = 2, sum = a + b, myobject = {}, i, j; // function body... }
您可以使用一个var语句声明多个变量,并以逗号分隔。像这种初始化变量同时初始化值的做法是很好的。这样子可以防止逻辑错误(所有未初始化但声明的变量的初始值是undefined)和增加代码的可读性。在你看到代码后,你可以根据初始化的值知道这些变量大致的用途。
以上就是针对javascript的var预解析与函数声明提升的学习内容,希望对大家的学习有所帮助。